SpringCloud 面试问题

dubbo cloud 中区别:

dubbo:  RPC方式实现服务间调用 数据库是一个   每个服务 都需要引入dao层依赖  访问操作的数据库都是同一个 

cloud: Http 方式实现服务间的调用  每个服务间可以拆分更加细化 ,同时每个服务都可以独立部署 ,并且每个服务可以有自己独立的数据源

用户服务[对用户的数据维护操作]   用户数据库 [与用户相关的数据表]

### 微服务架构

​    微服务可以在“自己的程序”中运行,并通过“轻量级设备与HTTP型API进行沟通”。关键在于该服务可以在自己的程序中运行。通过这一点我们就可以将服务公开与微服务架构(在现有系统中分布一个API)区分开来。在服务公开中,许多服务都可以被内部独立进程所限制。如果其中任何一个服务需要增加某种功能,那么就必须缩小进程范围。在微服务架构中,只需要在特定的某种服务中增加所需功能,而不影响整体进程的架构 --来源百度

微服务指的就是 一个可以单独运行的程序 并且可以被外部访问调用(轻量级)

​    Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性简化了分布式系统的开发,比如服务发现、服务网关、服务路由、链路追踪等。Spring Cloud 并不重复造轮子,而是将市面上开发得比较好的模块集成进去,进行封装,从而减少了各模块的开发成本。换句话说:Spring Cloud 提供了构建分布式系统所需的“全家桶”。

## SpringCloud优点

1. 集大成者,Spring Cloud 包含了微服务架构的方方面面。

2. 约定优于配置,基于注解,没有配置文件。(扯淡)

3. 轻量级组件,Spring Cloud 整合的组件大多比较轻量级,且都是各自领域的佼佼者。

4. 开发简便,Spring Cloud 对各个组件进行了大量的封装,从而简化了开发。

5. 开发灵活,Spring Cloud 的组件都是解耦的,开发人员可以灵活按需选择组件。


在分布式架构中  有许多问题需要解决:

1.前台应用web(pc app  由于每个服务会分开部署 那么进行访问时  调用的接口地址不能统一)  统一网关处理

2.当应用越来越庞大时 ,部署的服务也好越来越多  服务间的调用链路也会越来越长    服务间的快速失败响应

当一个请求到达  一个服务时 ,这服务需要调用其他的服务 另外的一个服务由于网络原因会出现问题导致整个响应时间过长 , 请求的线程得不到释放 请求大量积压 最终导致服务器资源耗尽 服务宕机

0-1

在dubbo中 想要集成一些分布式开发中常用的一些处理措施技术时需要额外去添加这个组件,并且配置非常复杂.

原生SpringCloud中虽然是集成了这个组件 但是需要开发人员收动配置,并且需要二次开发  0.5 ->1

800多个微服务架构

## Netflix

![1624180177743](assets/1624180177743.png)

​    Netflix(Nasdaq NFLX) 译为奈飞或网飞,是一家会员订阅制的流媒体播放平台 ,总部位于美国加利福尼亚州洛斯盖图。成立于1997年,曾经是一家在线DVD及蓝光租赁提供商,用户可以通过免费快递信封租赁及归还Netflix库存的大量影片实体光盘

![1624180497920](assets/1624180497920.png)

## SpringBoot

​    Spring Boot 是由 Pivotal 团队提供的基于 Spring 的全新框架,其设计目的是为了简化 Spring 应用的搭建和开发过程。该框架遵循“约定大于配置”原则,采用特定的方式进行配置,从而使开发者无需定义大量的 XML 配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域成为领导者。

Spring Boot 并不重复造轮子,而且在原有 Spring 的框架基础上封装了一层,并且它集成了一些类库,用于简化开发。换句话说,Spring Boot 就是一个大容器

## SpringCloud与Dubbo

dubbo并不是什么都没有 ,如果想要实现下面的技术需要手动进行复杂的配置才能完成

而cloud是已经组件这些依赖 只要简单的配置就可实现gateway zuul2 webflux 异步响应式编程\

服务众多  每个服务不同配置属性  800  10台服务负载 配置一样  其中一个配置需要更新

配置名称: 配置内容   平滑性的更改配置内容  

配置中心中保存 服务配置信息  当配置发生变更后  不需要主动的去更改每个服务的配置   而引入配置中心的服务会自动更新配置  而服务不需要重新启动即可获取最新的配置信息

![1607683717162](assets/1607683717162.png)

springcloud是一种将每个服务拆分为更细化的分布式架构,服务的调用 

微服务架构中对于服务的拆分没有一个严格的标准只有更合理的拆分体系

springcloud  - > springboot  

zk中服务发现与同步是一致性 

eureka 相互注册  体系 可用性    如果eureka注册后在注册中心没有发现 客户端时 是正常现象 需要等待最少30s后才能正常获取或显示注册的实例

# 服务注册与发现-Eureka

依赖:

```xml
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

      
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
```

## cloud&boot依赖引导通用设置

```xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

     <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

     <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
```

Eureka配置:

```yml
spring:
  application:
    name: cloud-eureka #服务名称
server:
  port: 9000 #端口
eureka:
  instance:
    hostname: localhost:${server.port} #实例注册地址
  client:
    fetch-registry: false 
    register-with-eureka: false 
    service-url:
      defaultZone: http://${eureka.instance.hostname} #注册的协议地址访问名称
```

​    eureka包含2个组件,Server和Client.Server服务端提供服务注册功能,提供者节点启动后会在Eureka中进行注册,这样EurekaServer的服务注册表中将会存储所有可用的服务节点信息.然后各个提供者将会向EurekaServer发送心跳.以告知EurekaServer自己的健康状况,默认周期为30秒.如果在多个心跳周期内(默认为30秒)没有接收到某个提供者的心跳,EurekaServer会认为其已无法提供服务,会将该提供者节点从服务注册表中移除.EurekaServer之间通过复制的方式完成数据的同步.

EurekaClient是一个java客户端,用于简化消费者与EurekaServer的交互,同时EurekaClient还内置有负载均衡器,为消费者从EurekaServer的服务注册表中选择合适的提供者.

Eureka提供了客户端缓存机制,即使所有的eurekaServer都挂掉客户端依然可以利用缓存中的信息为消费者提供服务发现功能,不过,此时不再接受服务注册,为EurekaServer已经全部挂掉,这是AP原则的体现.

## 创建服务提供者

引入依赖

```xml
其他的依赖找boot项目的依赖添加
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
```

服务提供者其他组件(mysql mybatis-plus等)

```xml
 <dependencies>
      <!--应用监控  依赖  在1.5后需要手动加载和开启-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 数据持久层 -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>

        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>

        <!-- mybatis-plus 代码生成器 -->

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.0</version>
        </dependency>


        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.30</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- 日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!--swagger2的jar包-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--引入视觉的样式的UI-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.60</version>
        </dependency>

    </dependencies>
```

开启服务注册:

```java
@SpringBootApplication
@EnableEurekaClient
public class MemberApplication {

    public static void main(String[] args) {
        SpringApplication.run(MemberApplication.class,args);
    }
}
```

![1607700675635](assets/1607700675635.png)

## 服务消费

open-feign 约定  服务消费方在通过feing接口调用时   要与目标方法的请求方式  参数列表  返回类型  方法签名  完全一致才行

## actuator

​    在Spring Boot应用中,要实现监控的功能,只需要依赖组件spring-boot-starter-actuator。它提供了很多监控和管理你的spring boot应用的HTTP或者JMX端点,并且你可以有选择地开启和关闭部分功能。当你的spring boot应用中引入依赖之后,将自动拥有审计、健康检查、Metrics监控功能。

​    在Springboot2以前默认自动开启,升级到2.x之后需要手动开启并配置使用

actuator配置:

```yml
management:
  endpoints:
    web:
      base-path: /actuator
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always
```

# 客户端调用-Feign

​    feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。

在使用 feign时 在客户端 需要创建一个接口并且 接口的声明 返回类型 参数类型 请求方式一定要与服务提供方的控制层一致,否则无法调用

依赖:

```xml
  
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    <!--open Feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!--添加eureka 客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
```

客户端在进行调用时通过接口的方式进行调用获取

```java
@FeignClient(name = "order-service",path = "/order")
public interface OrderService {
    @GetMapping("/findOrder/{memberId}")
    public ServiceResult<List<Orders>> findOrderByMember(@PathVariable("memberId") Integer memberId);
}
```

# 客户端负载均衡-Ribbon

dubbo的负载均衡要配置在哪个层面: 服务层 设置负载均衡策略

商品服务-3台 goods-service-provirer 设置负载均衡策略

​    Ribbon是Netflix公司开源的负载均衡项目,是一个客户端负载均衡器,运行在消费端.

OpenFeign中内置了Ribbon无需额外引入,测试负载均衡器需要搭建多个服务提供者. 

Ribbon默认采取轮询算法

轮询算法

1. 随机 (Random)

2. 轮询 (RoundRobin) [默认]

3. 一致性哈希 (ConsistentHash)

4. 哈希 (Hash)

5. 加权(Weighted)

   ​    ribbon是一个为客户端提供负载均衡功能的服务,它内部提供了一个叫做ILoadBalance的接口代表负载均衡器的操作,比如有添加服务器操作、选择服务器操作、获取所有的服务器列表、获取可用的服务器列表等等. 负载均衡器是从EurekaClient(EurekaClient的实现类为DiscoveryClient)获取服务信息,根据IRule去路由,并且根据IPing判断服务的可用性。

# 服务网关-Zuul

在应用网关分两种

- 流量网关  nginx HTTPweb服务器[负载均衡  反向代理   外围网关]
- 服务网关  业务鉴权  流量控制等操作  当一个请求符合要求时   网关会向下路由,当网关的过滤器执行时不符合要求将会把这次请求中断

请求路由功能

客户端 --> nginx --> 前端 --> nginx访问的地址 --> 业务网关中进行处理

gateway网关 引入的依赖不要加入web

​    API 网关负责服务请求路由、组合及协议转换。客户端的所有请求都首先经过 API 网关,然后由它将请求路由到合适的微服务。API 网关经常会通过调用多个微服务并合并结果来处理一个请求,它可以在 Web 协议(如 HTTP 与 WebSocket)与内部使用的非 Web 友好协议之间转换.

依赖:

```xml
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
```

配置:

```yml
server:
  port: 80
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka
zuul:
  routes:
    order-consumer: /order/**
    member-consumer: /member/**
  ignored-services: '*'
  host:
    connect-timeout-millis: 10000
    socket-timeout-millis: 10000
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000
spring:
  application:
    name: cloud-gateway
```

### 网关认证

`网关`统一做路由处理,做认证

SpringCloud下通常使用需要安全保护的有两处,分别为系统认证和服务内部鉴权。

有些在访问时需要获取用户的身份信息时  这时就要在每个服务中都要进行过滤判断

servletFilter

创建一个java类型  实现filter接口  在doFilter方法中编写过滤业务规则,当业务处理符合要求时正常放行,如果在过滤器执行业务代码不符合过滤器执行的要求时请求将会中断,  导航处理  提示用户或者在filter中进行重定向到登录请求

ZuulFilter 当符合要求时  向下进行正常路由,如果不符合过滤器的规则要求时 将路由请求中断  要响应给前台一个信息

### Filter

filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:

- `pre`:可以在请求被路由之前调用
- `route`:在路由请求时候被调用
- `post`:在route和error过滤器之后被调用
- `error`:处理请求时发生错误时被调用

​     Zuul的主要请求生命周期包括“pre”,“route”和“post”等阶段。对于每个请求,都会运行具有这些类型的所有过滤器。

`filterOrder`:通过int值来定义过滤器的执行顺序,数值越小越优先

`shouldFilter`:返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关。在上例中,我们直接返回true,所以该过滤器总是生效

`run`:过滤器的具体逻辑。需要注意,通过`RequestContext.setSendZuulResponse(false)`令zuul过滤该请求,不对其进行路由,然后通过`RequestContext.setResponseStatusCode(状态值)`设置了其返回的错误码

![1607854106628](assets/1607854106628.png)

# 服务熔断-Hystrix

![1607834383281](assets/1607834383281.png)

`服务熔断`就是当服务出现短时不可用时  会快速回退

`服务降级`就是目标停止服务

当服务a需要完成业务时需要向服务b服务c进行调用访问并返回数据进行处理

其中一个服务正在运行过程中出来了问题  在服务a里面服务a将不能正常执行,程序还会正常执行,每次返回服务a的结果都是`服务异常的结果`

500错误信息

服务a正在访问的服务b或服务c时  由于网络原因过长  响应时间很长 

请求链路长[网络开销也长  响应时间长 ]  在等待3-5秒后请求线程并不会释放,只有在请求后响应回来才能进行释放,如果一直等待响应线程得不到释放

一个用户一个响应得不到释放如10个100个100个都得不到释放 最终导致服务资源耗尽

一个正常请求  响应的时间应该在200ms  服务后端业务处理比较复杂 1-2m内完成并返回

当客户端在向后端发送请求时不管是服务间出现异常还是每个服务调用时间过长   都需要给客户端一个即时反馈,如果没有反馈用户一直等待可能导致服务资源耗尽

解决方案:

快速失败回退   服务a向服务b发送请求时  只会最多等待2秒钟  如需等待时间过长,最多等待2秒种做出返回客户端反馈  -----> 服务熔断

服务熔断:当一个服务在执行过长中出现异常或等待超时会快速做一个返回   请求线下得到释放

服务降级  将目标服务之间直接停止不在对外进行服务(主动停止降级)

将某一业务停止后:

将原有得非核心资源分配给核心服务

非核心业务影响到核心业务[订单是核心服务,将业务进行部署发布,  其服务中某一项功能出现异常会影响到后续得业务  业务应用越长会影响发生异常得几率越高]  

对这个方法有一个  处理快速失败得处理回退方案  需要编写一个返回类型一致得  fallback方法

当一个服务接口业务很多时  那么就意味着所有得接口feign都要编写  fallback

​    分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服务资源耗尽,无法继续对外提供服务。并且这种不可用可能沿请求调用链向上传递,这种现象被称为雪崩效应。

![1607827781586](assets/1607827781586.png)

## **雪崩效应常见场景**

- 硬件故障:如服务器宕机,机房断电,光纤被挖断等。
- 流量激增:如异常流量,重试加大流量等。
- 缓存穿透:一般发生在应用重启,所有缓存失效时,以及短时间内大量缓存失效时。大量的缓存不命中,使请求直击后端服务,造成服务提供者超负荷运行,引起服务不可用。
- 程序BUG:如程序逻辑导致内存泄漏,JVM长时间FullGC等。
- 同步等待:服务间采用同步调用模式,同步等待造成的资源耗尽。

## **雪崩效应应对策略**

针对造成雪崩效应的不同场景,可以使用不同的应对策略,没有一种通用所有场景的策略,参考如下:

- 硬件故障:多机房容灾、异地多活等。

- 流量激增:服务自动扩容、流量控制(限流、关闭重试)等。

- 缓存穿透:缓存预加载、缓存异步加载等。

- 程序BUG:修改程序bug、及时释放资源等。

- 同步等待:资源隔离、MQ解耦、不可用服务调用快速失败等。资源隔离通常指不同服务调用采用不同的线程池;不可用服务调用快速失败一般通过熔断器模式结合超时机制实现。

- 舱壁隔离  可以体现在负载均衡中 [3台服务器进行服务, Hystrix监控每个服务 ,当其中一个服务在运行时出现异常 Hystrix会监控 当一个服务异常达到比率50%打开短路器,当客户端发送服务调用时不再向这台服务器发送请求,一段时间内 Hystrix 进行尝试(似开启似关闭状态),如果还是出现异常将彻底关闭,如果正常运行短路器关闭]

  

  ​    

![1607828998268](assets/1607828998268.png)

Hystrix设计目标:

- 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
- 阻止故障的连锁反应
- 快速失败并迅速恢复
- 回退并优雅降级
- 提供近实时的监控与告警

依赖:

```xml
      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
```

### 业务异常

主类上加入@EnableHystrix注解开启服务断路:

```java
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix//开启
public class OrderConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderConsumerApplication.class,args);
    }
}
```

测试:

```java
@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/findOrder/{memberId}")
    @HystrixCommand(fallbackMethod = "findOrderFallback")
    public R<List<Orders>> findOrderByMemberId(@PathVariable("memberId") Integer memberId){
        R<List<Orders>> r=new R<>();
        ServiceResult<List<Orders>> serviceResult=this.orderService.findOrderByMember(memberId);
        BeanUtils.copyProperties(serviceResult,r);
        return  r;
    }

    public R<List<Orders>> findOrderFallback(@PathVariable("memberId") Integer memberId){
        return new R(R.CODE_FAIL,"系统繁忙");
    }
}
```

服务提供方代码:

```java
 @GetMapping("/findOrder/{memberId}")
    public ServiceResult<List<Orders>> findOrderByMember(@PathVariable("memberId") Integer memberId){
        System.out.println(1/0);//运行时出现异常
        QueryWrapper<Orders> queryWrapper=new QueryWrapper<>();
        Orders o=new Orders();
        o.setMember(memberId);
        List<Orders> ordersList = this.ordersService.list(queryWrapper);
        return new ServiceResult<List<Orders>>(ServiceResult.CODE_SUCCESS,ServiceResult.MESSAGE_SUCCESS,ordersList);
    }
```

结果:

![1607826270208](assets/1607826270208.png)

在feign的调用方法中通过创建一个与业务方法返回类型参数类型完全一致的方法用于处理该方法调用的失败业务.

### 服务超时

将服务提供方执行代码设置线程休眠

```java
@GetMapping("/findOrder/{memberId}")
    public ServiceResult<List<Orders>> findOrderByMember(@PathVariable("memberId") Integer memberId){
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        QueryWrapper<Orders> queryWrapper=new QueryWrapper<>();
        Orders o=new Orders();
        o.setMember(memberId);
        List<Orders> ordersList = this.ordersService.list(queryWrapper);
        return new ServiceResult<List<Orders>>(ServiceResult.CODE_SUCCESS,ServiceResult.MESSAGE_SUCCESS,ordersList);
    }

```

feign中配置hystrix超时时间:

==以下代码不会有任何提示,复制粘贴进去!!!==

```yml
hystrix:
  command:
    default:  #default全局有效,service id指定应用有效
      execution:
        timeout:
          #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 4000 #断路器超时时间,默认1000ms
```

zuul网关中加入配置:

```yml
zuul:
  host:
    connect-timeout-millis: 10000
    socket-timeout-millis: 10000
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000
```

**线程隔离**:Hystrix在用户请求和服务之间加入了线程池。Hystrix为每个依赖调用分配一个小的线程池。用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满调用将被立即拒绝,进行降级处理,用户的请求不会被阻塞,至少可以看到一个执行结果(例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。

**信号量隔离**:每次调用线程,当前请求通过计数信号量进行限制,当信号大于了最大请求数时,进行限制,调用fallback接口快速返回

找hystrix通过信号量隔离机制设置一个请求最大数,测试  每秒中请求100个

### 附录-Hystrix仪表板 

启动后地址栏输入的地址加localhost:端口/hystrix显示监控首页,在下面的地址栏中输入要监控的地址信息,被监控的服务需要加入actuator组件并开启服务端点. 如果监控时长时间没有反应既正在加载时 通过浏览器或其他前端工具手动向北监控的服务发送一个请求

![1607834022926](assets/1607834022926.png)

![1607834045151](assets/1607834045151.png)

在监控的界面有两个重要的图形信息:一个实心圆和一条曲线。

  **▪实心圆:**1、通过颜色的变化代表了实例的健康程度,健康程度从绿色、黄色、橙色、红色递减。2、通过大小表示请求流量发生变化,流量越大该实心圆就越大。所以可以在大量的实例中快速发现故障实例和高压实例。

  **▪曲线:**用来记录2分钟内流量的相对变化,可以通过它来观察流量的上升和下降趋势。

依赖:

```xml
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

```

SpringCloud2.x开始 需要额外加入Servlet配置才能正常监控访问熔断流

```java
 @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
```

![1607834421299](assets/1607834421299.png)

# 应用服务配置中心-Config

通过配置中心用于维护各个微服务的配置选项

每个微服务中会有配置文件   那么一旦有写配置发生变化时   需要手动去维护各个服务里面配置文件并重启微服务

除非你的参数是每次使用时读取一次

​    1.服务多

​    2.有写服务属于访问量很大  所以在部署时需要做负债均衡 3

​    会员服务中一个属性值  这个值会发生改变

Spring Cloud Config是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

什么是config

- 服务端也称为分布式配置中心,它是一个独立的微服务应用,睐连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口
- 客户端则是通过指定的配置中心来管理应用资源,以吸与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容

可以做

- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta/release
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
- 将配置信息以REST接口的形式暴露

GitHub设置

![1607834776473](assets/1607834776473.png)

![1607834809261](assets/1607834809261.png)

![1607834823205](assets/1607834823205.png)

再次之前如果没有SSH信任秘钥需要创建生成

![1607834916156](assets/1607834916156.png)

https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/connecting-to-github-with-ssh

![1607834944377](assets/1607834944377.png)

![1607834955949](assets/1607834955949.png)

![1607834983301](assets/1607834983301.png)

打开本地Git bash客户端

![1607835047231](assets/1607835047231.png)

![1607835166793](assets/1607835166793.png)

![1607835219206](assets/1607835219206.png)

![1607835258627](assets/1607835258627.png)

再次添加公钥信息

![1607835388331](assets/1607835388331.png)

![1607835403629](assets/1607835403629.png)

通过git bash 创建校验github ssh连接

```shell
 ssh -T git@github.com
```

```shell
The authenticity of host 'github.com (192.30.255.112)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.255.112' (RSA) to the list of known hosts.
Hi zhaoran0813! You've successfully authenticated, but GitHub does not provide shell access.
```

出现以上信息证明可以了 如果还是需要验证就进入到.ssh目录下打开git bash

```she
 eval `ssh-agent`
 ssh-add id_rsa
```

在 git bash中 从github上clone下创建的库

```shell
git clone 你的库地址
```

![1607840526454](assets/1607840526454.png)

cd 到目录内部 vim 创建一个文件 随便编写几句内容

```shell
zhaoran@DESKTOP-IIU38NP MINGW64 /d/gitRepository/spirngcloud-config-Repository (m                  aster)
$ vim t.txt

zhaoran@DESKTOP-IIU38NP MINGW64 /d/gitRepository/spirngcloud-config-Repository (m                  aster)
$ git add t.txt ###文件加入暂存区
warning: LF will be replaced by CRLF in t.txt.
The file will have its original line endings in your working directory.

zhaoran@DESKTOP-IIU38NP MINGW64 /d/gitRepository/spirngcloud-config-Repository (m                  aster)
$ git commit -m "commit file" t.txt ###提交文件
warning: LF will be replaced by CRLF in t.txt.
The file will have its original line endings in your working directory.
[master (root-commit) 85daf53] commit file
 1 file changed, 1 insertion(+)
 create mode 100644 t.txt
git push   ###push到 github中
Logon failed, use ctrl+c to cancel basic credential prompt.
Username for 'https://github.com': zhaoran0813@gmail.com
Counting objects: 3, done.
Writing objects: 100% (3/3), 203 bytes | 203.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/zhaoran0813/spirngcloud-config-Repository.git
 * [new branch]      master -> master

```

![1607840720562](assets/1607840720562.png)

本地提交测试完成

config 访问规则

member-feign/application.yml

```undefined
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties 
```

label 为分支,application 为应用名,profile 为环境信息

### 创建SpringCloud-config -Server项目 

这个项目就是配置中心服务器

依赖:

```xml
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
```

配置文件要用bootstar命名

![1607847704274](assets/1607847704274.png)

bootstrap.yml 内容:

```yml
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/zhaoran0813/spirngcloud-config-Repository.git
          ignore-local-ssh-settings: true
          force-pull: true
          private-key: |
                          -----BEGIN RSA PRIVATE KEY-----
                          MIIJKAIBAAKCAgEAyz8Q5Xh5FOELwb/cxAbEgEQRNpBcYEBNhPwbNGvPhNwUHkds
                          uz2bae5K6Fj1ZfLB95caj2HC/ZrNpF/JCUy8svHm5tr7axT8K3xKHzioy1X6fgp0
                          F4F0vSralgfBvGVqK1jcKv8zIpUZ0b3Jft7B8leiOq4J9i3k0ijK0mPufErlGNd0
                          Y7UJqPQbpqNPcaLagnhuAUmS/4VF7Nxc0duEq/N8vy6Byy48JdDdkw45pQ228wVU
                          sOR2FN61Fgy7U6vE4gZzh93SCJJGPv8LMSR9XlkVfurv/wGPkVA1kwi1D55gssb5
                          vunXu2ZgLK/Y0iF1giOHMlKgHBCn9IVx1EI3aooC01nTAEGq/dWjKKgjnSVNR+ok
                          INkpOJfc2/nCbJvSHmoqOZILiRbvgb/LdXVWOYgtTU891WTv5RYLw2WvW5mvQ+TZ
                          ufhVeflusjiRQno2JkPt1VZW2Hmhd1EQM9F87g+M+1+UGmGcn75StAJyo2rlp3BZ
                          Kmh8LFESdI3QxU+4syG8JmLBCMs2K8RLYi6mDX85NngM8qCPV9jmKAIgdMVbcgEQ
                          ffeSFwFpjhgegS/bBy+DfxUopm/OOnatMRiwfmz8E09Y8lkGzzg+XbUGmIa85HqG
                          IAuyZPr5GGDf8dBGXFpZWCChyHeD8X6CutEwFS8JyG9Jzv1j3XCbnxvNSc0CAwEA
                          AQKCAgBAEyjLfxiFCZHASjFaJ1wJp+vZTNeijIMj2qrk8twgYZWCGjhgK0L0uWgq
                          Kelrc4XM/XklHMfxVb1hBcWGRgfzTiniO8UpdBsvxmZDw4QLXpay567Dvk9EV99D
                          jzx3nW1ELyZx87R2QZU7N17vvWBde10srLN9ReiujKesfk6wJphlJX+O84MRHawd
                          87xW8eV7XmYnx78tCSILU0l7632/C+sXBp1qpa/WqCtCciigLVuw78xMXCoR2Eg0
                          pFzmOu+95hTED51okFzO/W7U1lEjzmfldEGnHiHZyPSq3wLd4qtPkUUo9+XIMbU+
                          QU3UqTG3jmXP6paJYoLgprVFGn8Haj/g2DmOd92EofGeEseiOoLPDsrsw26XghIK
                          OYWySGIb8J4riKOL2n+dZ01kVO5PZn7ZJuhOThxALi7m1UFdMo+U3O/+g+SlmiR8
                          xj9W335MsE5wFQ+OvY2tXZQUFCggqINuq60/48qKBWgZp71jd18UEidtP/e67JUP
                          pshJCGN5EymUFdenLN4dm5t4SuaY9HBO/ovr4VpJkHtOm5cSfsOHOtsuoWyUEekG
                          jlkXXeSSSH5P9qoeQEkafCg88sCx6mABp7g9uSjuYQWWrVNDV9pXN83CQ1XeRSVo
                          DcMgQsb3jaEs/8da4XcKmTtThE36aiYoiQ5I6biT6toPBT9QLQKCAQEA9KEfubF7
                          nj9An3mSW8/AXPH3leI+swFAM7X2kz2acrctl9LxCgv06LlUPFTcWQBYTRg6Q5YR
                          gdMn69H5d8VnPkHj+HT7E+LhreZiYjVX2BKtABmpzI0Fh6/LjWcCq7obeP/CYb9i
                          aXS1JfYHdIRpywbDYDtcioTsblib4WvlaoWqo1KzpZrhHBgQe7Neuv7EXbsURwDQ
                          mo67yRupav93e/A5Eh4IbynE9rWP3d6LM6QZlcvpF5lelL2T4TEgyMRlrOIT5r1l
                          1e5zDagORIWwKKYUU1ku8/WZm0WhBn3KrfdVnEdPmuxjoSDeb9AF0SSCwifVx5/Z
                          gYTMbydWE+Ox+wKCAQEA1LGFIpXhjKjhSXa3vDR6Kjdi/oDCHX2jjsS4+TxTmmL8
                          yCeT+rVkDibQlfoqNjYU6fiX0A0najLtPBRVBeltsrvAcF3QU8MHIXDbkXdsBFfu
                          yy5UtKbMbSM1ix4ZvSuZUtx7ekHcBnMBTr+i2snLY6Vn6EZabqy1rZ7YN4cWR/6w
                          oydttyrs1cwQL2P8rpWB0R/sW0/6W6sN5WFCy4tsNWIUCsiPkfU+a+4ccX20zIyR
                          rLEmSlretHoFtwRIk9ny3y2JgQr+8hsaojST7Dxa7blAaLvj28c7a7+kwxsLJSSv
                          Fa/eNZZVzDDLBAS130D6fdNhbF1/YKsLELg5VA9w1wKCAQATmLyz4XXnrWV94P1K
                          gZAFYhTVWvRu3pDIE7GXBf5TZj0uxmUsytxpsD8BPkMQlih8tI4mT+VDIyk1iPKV
                          F6k3oYujoatjYm91wNjsyR0qYASf1250xm9E+V4zC6d5HkWJIePudKhrjj/ctKLQ
                          QLNA4l/QW7EEH7XY+RwzqLMOH3sV7lAZ2hhiacMYRbw2+qW8ZHoxXe1YFEsSxzaB
                          LcnikdHgk6tVTGFM6iqGOYepMWIjT9xyWYTsIWuxRIA91Q3YFZxGhbGcu6dX1rid
                          4J/GAdfq/V/3hxsxBxjpLjaITSH8jPHhlUI97CYliuKMaIJZD1vey/1elMbTuLD6
                          kuj1AoIBAAYvi4Gv/jlLCBJM45cTp6HmrnhcYkjdSI50ZjTJbl0FF/jyPbmC4QAQ
                          XOyfs+6TsBQF6NRiLY1HIeMnbDmZyljyYOxjrhVhjKmKULhwUrHlpMo/9LK0Tym1
                          Zm8/VtxLkk/4nZa2p6GAYr9Zj3DxgXrKarU0ppilaTs9bWhgA2Pgol58XRKAqxak
                          sqvOKqEhM/9TAFq/frZ/yQ2swHaO/Xyn95FAt/w0t7YH3MfoMgPo6qutE0ICVovF
                          KLlj5IB4TDn1ZxRbr4J3C1VAVjT+pF5Zjuf83umbZ70Ae9g4xyAzauwkiz/fuWsQ
                          2DartGZjy2UxapnuNjAniVDZKsGpGU0CggEBALT/8eXEzMEFGPjAgiAjEskxPDZl
                          Tu+jT2haj8i0iewVXEDRTI2Y7GU7/D4Nowpw6DpEMQWV6fxPMthzlBYDy4ICmJ8U
                          YeZSW5JA862RZC/RV2lXITEDSFLI9ImGYpJCvky4bsdLgq/sKYLGDg1HvPSSvIyg
                          QbCgsI+CG7hfERcfaoTrevjb59umcAcYZEFujUc0Jx6U1rGX5/UnZy9zB4o8ABxF
                          WmyhBiduHfElHrCM4OqCj/uREdWmaZX3Fzevofx2ELKEjeBkHQeUT56JPbwOq0bo
                          WTS+tXHCA97NaR1UrrhkjM9+BbvSkkJYtRkAZsCTDz35vBrxd2jLdLvSsIk=
                          -----END RSA PRIVATE KEY-----
          search-paths: /spirngcloud-config-Repository
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka
```

编写启动类文件:

```java
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class ServerConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServerConfigApplication.class,args);
    }
```

从任意一个cloud项目中复制一个yml配置文件在里面随意加入点内容,粘贴到git的仓库文件目录中,更改名称

![1607847473007](assets/1607847473007.png)

![1607851648145](assets/1607851648145.png)

通过git bash将这个文件push到github中

![1607851973212](assets/1607851973212.png)

![1607852397730](assets/1607852397730.png)

### 客户端配置

依赖:

```xml
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
```

配置文件同样需要创建一个bootstart.yml编写配置中心信息

```yml
spring:
  cloud:
    config:
      name: order-service-application #需要从github上读取的资源名称,注意没有yml后缀名
      label: master
      uri: http://localhost:8000/  #通过SpringCloudConfig获取GitHub的服务地址
```

![1607852742286](assets/1607852742286.png)

![1607852771200](assets/1607852771200.png)

配置完成后启动注册中心微服务 配置中心微服务 客户端微服务

配置中心启动后可以通过浏览器地址栏对配置进行访问,如果没有500并显示配置文件内容代表正常.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值