微服务springcloud介绍

一 微服务介绍

1 单体架构

是一种传统的架构风格,单体架构时,将业务模块写在一个项目中,最终打包成war包,然后部署

单体架构的缺陷:
1)复杂性高
整个项目包含的模块非常多,模块的边界模糊,依赖关系不清晰,代码质量参差不齐,整个项目非常复杂。每次修改代码都心惊胆战,甚至添加一个简单的功能,或者修改一个BUG都会造成隐含的缺陷。

2)技术债务逐渐上升
随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务,并且越积越多。已使用的系统设计或代码难以修改,因为应用程序的其他模块可能会以意料之外的方式使用它。

3)部署速度逐渐变慢
随着代码的增加,构建和部署的时间也会增加。而在单体应用中,每次功能的变更或缺陷的修复都会导致我们需要重新部署整个应用。全量部署的方式耗时长、影响范围大、风险高,这使得单体应用项目上线部署的频率较低,从而又导致两次发布之间会有大量功能变更和缺陷修复,出错概率较高。

4)扩展能力受限,无法按需伸缩
单体应用只能作为一个整体进行扩展,无法结合业务模块的特点进行伸缩。

5)阻碍技术创新
单体应用往往使用统一的技术平台或方案解决所有问题,团队的每个成员都必须使用相同的开发语言和架构,想要引入新的框架或技术平台非常困难。

2 什么是微服务

微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”。

In short, the microservice architectural style [1] is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

3 微服务的优势

复杂度可控:在将应用分解的同时,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可维护性和开发效率。

独立部署:由于微服务具备独立的运行进程,所以每个微服务也可以独立部署。当某个微服务发生变更时无需编译、部署整个应用。由微服务组成的应用相当于具备一系列可并行的发布流程,使得发布更加高效,同时降低对生产环境所造成的风险,最终缩短应用交付周期。

技术选型灵活:微服务架构下,技术选型是去中心化的。每个团队可以根据自身服务的需求和行业发展的现状,自由选择最适合的技术栈。由于每个微服务相对简单,故需要对技术栈进行升级时所面临的风险就较低,甚至完全重构一个微服务也是可行的。

容错:当某一组建发生故障时,在单一进程的传统架构下,故障很有可能在进程内扩散,形成应用全局性的不可用。在微服务架构下,故障会被隔离在单个服务中。若设计良好,其他服务可通过重试、平稳退化等机制实现应用层面的容错。

扩展:单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。

4 微服务组件模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Scbhihdn-1576816067127)(cloudpic\1-1.jpg)]

1)请求统一通过API网关(Zuul)来访问内部服务.
2)网关接收到请求后,从注册中心(Eureka)获取可用服务
3)由Ribbon进行均衡负载后,分发到后端具体服务实例
4)微服务之间通过Feign进行通信处理业务
5)Hystrix负责处理服务超时熔断
6)Turbine监控服务间的调用和熔断相关指标

二 注册中心

1 原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OJFNmiaE-1576816067129)(cloudpic\2-1.png)]

服务提供方启动后将注册到注册中心,提供IP, 名字,什么服务等信息,
服务调用方作为客户端注册到注册中心后,拉取注册中心的服务列表,在通过负载均衡调用对应的服务提供方。
注册中心可以建立集群,生成多台eureka,注册中心为了监测各个服务的心跳,将在每30S 向所注册的服务发起请求判断服务是否挂掉,如果挂掉90S后将会将服务从注册中心剔除。
一个服务可以监测多台服务实例,从而可实现均衡负载。

2 注册中心服务端

1)导入jar

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

2)启动类上使用注解 :

@EnableEurekaServer

@SpringBootApplication
@EnableEurekaServer
public class MicroEurekaApplication {

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

}

3)配置文件

server:
  # eureka服务端的端口,默认是8761,如果不设置,是8080
  port: 8761

4)启动

日志上可以看到类似内容

INFO 2300 --- [           main] c.n.eureka.cluster.PeerEurekaNodes       : Replica node URL:  http://localhost:8761/eureka/

输入地址:localhost:8761,展示如下页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rpJD4t64-1576816067129)(cloudpic\1.png)]

6)指定服务名称

上图中,Application项是UNKNOW,如果想使用指定的名称

spring:
  application:
    name: micro-server

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eeZyWTcO-1576816067130)(cloudpic\2.png)]

7)服务中心不作为客服端注册自己

另外,直接启动,会看到报了一些异常,原因在于,服务中心,也可以作为客户端,默认情况下会尝试找服务中心注册自己,开始没有找到,所以可以指定一个defaultZone,另外服务中心不需要注册自己,修改配置:

server:
  # eureka服务端的端口,默认是8761,如果不设置,是8080
  port: 8761
spring:
  application:
    name: micro-server
eureka:
  client:
    serviceUrl:
      # 客户端使用的服务路径
      defaultZone: http://localhost:8761/eureka/
    #是否将自身注册到eureka
    register-with-eureka: false
    #是否抓取注册信息
    fetch-registry: false

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMkNKBps-1576816067130)(cloudpic\3.png)]

8)其他一些配置

spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      # 客户端使用的服务路径
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      #是否将自身注册到eureka
    register-with-eureka: false
    #是否抓取注册信息
    fetch-registry: false
  server:
  	# 清理间隔
    eviction-interval-timer-in-ms: 5000
    # 是否开启eureka服务器的自我保护
    enable-self-preservation: true
  instance:
    lease-renewal-interval-in-seconds: 30 #每30S给其他服务发次请求,监测心跳
    lease-expiration-duration-in-seconds: 90 #如果其他服务没心跳,90S后剔除该服务

3 客户端

1)导入jar

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

如果还需要其他jar,比如mybatis等,额外导入即可

		<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>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.0</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>
		

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

		<!-- pagehelper -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper-spring-boot-starter</artifactId>
			<version>1.2.12</version>
		</dependency>

2)启动类上,使用@EnableEurekaClient

3)配置文件

server:
  port: 7001

spring:
  application:
    name: micro-bank
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/bank1905?serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      max-active: 20
      initial-size: 5

# 作为eureka的客户端,指定eureka服务的注册地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    #客户端拉取注册中心的服务列表
    # registry-fetch-interval-seconds: 50 

mybatis:
  type-aliases-package: com.rr.micro_bank.entity
  mapper-locations: classpath:mapper/*.xml

pagehelper:
    helperDialect: mysql

4)先启动注册中心,再启动其他服务程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yh8m1Ucw-1576816067130)(cloudpic\4.png)]

正常在浏览器中发送请求即可验证

4 Eureka 的自我保护机制与剔除服务机制

剔除服务机制:当服务提供方(客户端)注册到Eureka后,每30S将会向Eureka发起一次请求表示自己有心跳,
证明服务器正常;当90S都没有发请求时候Eureka会认为服务器宕机了,则会在60S后统一清除所有宕机的服务器。

自我保护机制:当服务没有按每30S按时发请求时,Eureka将会统计15分钟内心跳的请求成功概率,如果低于85%,则可能服务提供方有延迟问题或者网络故障,这样会将服务提供方保护起来不会剔除。

5 注册中心高可用

1)CAP原则

又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

Eureka 的设计原则是 AP,即可用性和分区容错性。他保证了注册中心的可用性,但舍弃了数据一致性

2)高可用配置

为了使eureka高可用,挂掉后依然可以使用,所以将配置多台eureka注册中心实现集群。
实现原理:如果需配置3台注册中心,那么应该是A注册到B、C ,B注册到C、A ,C注册到A,B。这样互相注册即可实现集群配置

本例中,给出两台eureka服务器

服务端配置

第一台:
server:
  port: 8761

spring:
  application:
    name: micro-server

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8762/eureka/
      
第二台:
server:
  port: 8762

spring:
  application:
    name: micro-server

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

客户端配置

eureka:
  client:
    service-url:
      # 配置所有的eureka地址
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

三 ribbon

是一个客户端的负载均衡器,它提供对大量的HTTP和TCP客户端的访问控制。

客户端负载均衡即是当浏览器向后台发出请求的时候,客户端会向 Eureka Server 读取注册到服务器的可用服务信息列表,然后根据设定的负载均衡策略(没有设置即用默认的),抉择出向哪台服务器发送请求。

注:

负载均衡:在集群中有服务器A、B、C,它们都是互不影响,互不相干的,任何一台的机器宕了,都不会影响其他机器的运行,当用户来一个请求,由负载均衡器的算法决定由哪台机器来处理,假如你的算法是采用round算法,有用户a、b、c,那么分别由服务器A、B、C来处理;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-blJlCBY4-1576816067131)(cloudpic\3-1.png)]

1 使用

注意:ribbon在客户端进行配置

1)导jar包

使用ribbton,需要如下jar包,但是在导入erueka-client的jar时,已经依赖该jar了,所以可以不写

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

2)调用方式

通过RestTemplate对象调用其他的微服务程序的接口

	@Autowired(required = false)
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancerClient;    

		// 方式1:直接调用
        JsonResult result = restTemplate.getForObject("http://localhost:7001/balance.do?bankCode={bankCode}", JsonResult.class, map);
        JsonResult result = restTemplate.getForObject("http://localhost:7001/balance.do?bankCode={1}", JsonResult.class, bankCode);

        // 方式2:如果有多个服务端,通过负载均衡对象
        ServiceInstance serviceInstance = loadBalancerClient.choose("MICRO-BANK");
        String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort())+"/balance.do?bankCode={1}";
        JsonResult result = restTemplate.getForObject(url, JsonResult.class, bankCode);

        // 方式3:在配置类中使用@LoadBalance注解
        JsonResult result = restTemplate.getForObject("http://MICRO-BANK/balance.do?bankCode={1}", JsonResult.class, bankCode);

使用负载均衡的配置类

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced // 开启负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

2 自定义负载均衡

默认的负载均衡方案是轮询,如果想使用其他方案,可以增加如下配置类:

@Configuration
public class MyRuleConfig {

    @Bean //修改轮询规则为随机
    public IRule iRule(){
        return new RandomRule();
//        return new RoundRobinRule();
    }
}

然后,在启动类上,使用注解

@RibbonClient(name = "micro-bank", configuration = MyRuleConfig.class)

注:

负载均衡的策略

com.netflix.loadbalancer.RandomRule 随机
com.netflix.loadbalancer.RoundRobinRule 轮询
com.netflix.loadbalancer.RetryRule 重试
com.netflix.loadbalancer.WeightedResponseTimeRule 响应时间权重
com.netflix.loadbalancer.BestAvailableRule 最空闲连接策略

3 RestTemplate使用

RestTemplate是spring提供的可以提供访问rest服务的客户端工具类,提供多种快捷的访问远程的方法,大大提高了客户端的编程效率。

常用方法:

1)getForObject

通过get请求方式访问指定路径

// 第一个参数,表示路径,第二个参数,返回值类型,第三个参数,路径中需要使用的参数
JsonResult result = restTemplate.getForObject("http://localhost:7001/balance.do?bankCode={bankCode}", JsonResult.class, map);

JsonResult result = restTemplate.getForObject("http://MICRO-BANK/balance.do?bankCode={1}", JsonResult.class, bankCode);

2)postForObject

通过post方式访问指定路径,使用该方法时,会将提交的数据转为json格式,所以访问的资源对应的方法,需要@RequestBody修饰

// 第一个参数,表示路径,第二个参数,post请求时提交的参数,第三个参数,返回值类型,第四个参数,路径中需要使用的参数
JsonResult result = restTemplate.postForObject("http://MICRO-BANK/balance.do", map, JsonResult.class);

四 feign

通过RestTemplate调用其它服务的API时,传参比较麻烦,比如,参数须在请求的URL中进行拼接,如果有多个参数,拼接请求字符串方式效率低下。
Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。

Feign整合了Ribbon和Hystrix,所以不再需要显式地导入这两个组件。

1 基本使用

1)导jar包

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2)启动类上使用@EnableFeignClients

3)创建接口,通过客户端进行调用

// 指定要调用的url接口所在应用名称
@FeignClient("MICRO-BANK")
public interface FeignService {

    // 和服务提供者的的方法保持一致即可
    @RequestMapping("/balance.do")
    public JsonResult balance(String bankCode);
}

4)测试feign时,加断点情况下容易超时,解决方案:

a)方案1:

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 500000

b) 方案2:开启hytrix,配置ribbon的超时时间

2 feign的负载均衡处理

在使用@FeignClient注解的时候 是默认使用了ribbon进行客户端的负载均衡的,默认的是随机的策略,那么如果我们想要更改策略的话,需要修改消费者yml中的配置,如下:

micro-bank:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule #配置规则 最空闲连接策略
    ConnectTimeout: 500 #请求连接超时时间
    ReadTimeout: 1000 #请求处理的超时时间
    OkToRetryOnAllOperations: true #对所有请求都进行重试
    MaxAutoRetriesNextServer: 2 #切换实例的重试次数
    MaxAutoRetries: 1 #对当前实例的重试次数

负载均衡的策略

com.netflix.loadbalancer.RandomRule 随机
com.netflix.loadbalancer.RoundRobinRule 轮询
com.netflix.loadbalancer.RetryRule 重试
com.netflix.loadbalancer.WeightedResponseTimeRule 响应时间权重
com.netflix.loadbalancer.BestAvailableRule 最空闲连接策略

五 zuul

zuul拦截对应的api前缀请求做转发 转发到对应的 serverId上,在eureka服务上同一个serverId可以对应多个服务, 也就是说用同一个项目不同的端口注册两个服务,但是serverId是一样 zuul做转发的时候会结合eureka-server起到负载均衡的效果

1 基本使用

导入jar

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

配置

server:
  port: 9001

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: micro-zuul

启动类上增加@EnableZuulProxy

启动后,如果访问其他微服务应用的路径,例子如下:

http://localhost:9001/micro-bank/balance.do?bankCode=111111

基本格式:http://zuul的ip:zuul的端口/其他微服务应用的名称/路径
注意原来的微服务的地址也可以访问

2 路由配置

zuul:
  # 忽略可以路由的微服务,*表示所有的,还可以写具体的服务名,多个服务名之间只用逗号分隔
  ignored-services: '*'
  routes:
    # 将指定微服务的地址映射到指定的路径,比如 将micro-bank的路径映射到/bank/**路径,可以指定多个,用逗号分隔
    # 注意 如果设置ignored-services,原来的路由路径micro-bank能访问,如果不设置,micro-bank和bank都可以用
    micro-bank: /bank/** # 配置映射路径方案1

或者
zuul:
  ignored-services: '*'
  routes:
    aaa: # 方案2, aaa表示路由名称,可以随便写,没有特殊意义
      service-id: micro-bank
      path: /bank/**

3 zuul的filter

Zuul Filter有以下几个特征:
​ Type:用以表示路由过程中的阶段(内置包含PRE、ROUTING、POST和ERROR)
​ Execution Order:表示相同Type的Filter的执行顺序
​ Criteria:执行条件
​ Action:执行体

以下提供四种标准的Filter类型及其在请求生命周期中所处的位置:

​ PRE Filter:在请求路由到目标之前执行。一般用于请求认证、负载均衡和日志记录。
​ ROUTING Filter:处理目标请求。这里使用Apache HttpClient或Netflix Ribbon构造对目标的HTTP请求。
​ POST Filter:在目标请求返回后执行。一般会在此步骤添加响应头、收集统计和性能数据等。
​ ERROR Filter:整个流程某块出错时执行。

4 jwt用法

JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案

JWT的三个部分如下:JWT头、有效载荷和签名

jwt头:

​ {“type”:“jwt”,“alg”:“HS256”}

在上面的代码中,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);type属性表示令牌的类型,JWT令牌统一写为JWT(需要额外设置)。

有效载荷payload

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。

JWT指定七个默认字段供选择(不是必须的):
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
除以上默认字段外,还可以自定义私有字段,如下例:
{
“username”: “zhangsan”,
“id”: “123”
}

请注意,默认情况下JWT是未加密的,任何人都可以解读其内容,因此不要构建隐私信息字段,存放保密信息,以防止信息泄露。

签名Signature

签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

首先,需要指定一个密码(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名。

HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)

最终生成的jwt的字符串由三部分组成:

header(base64后的)
payload(base64后的)

Signature

例如:eyJ0eXBlIjoiand0IiwiYWxnIjoiSFMyNTYifQ.eyJ1c2VybmFtZSI6InpoYW5nc2FuIn0.C13IdXCyBs4oALrcttCBQ5LMsl0pTNxwgwqsVW7lSPs

5 用户中心鉴权

六 hystrix

用在客户端,参数参考:

https://blog.csdn.net/tongtong_use/article/details/78611225

1 服务降级和服务熔断

熔断机制是应对雪崩效应的一种微服务链路保护机制。
当某个服务不可用或者响应时间超时,会进行服务降级,进而熔断该节点的服务调用,快速返回自定义的错误影响页面信息。

2 ribbon中处理

1)需要额外导入hystrix的jar,某些注解(比如@HystrixCommand)需要用到该jar

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

2)启动类上使用@EnableCircuitBreaker 或者 EnableHystrix

3)在方法上使用注解

注意:方法上一定要使用@HystrixCommand修饰

@HystrixCommand(fallbackMethod = "errorFallback")
public JsonResult errorFallback() {
        return new JsonResult(1, "服务不可用");
    }

4)类中增加降级处理时的回调函数

注意:回调函数返回值和@HystrixCommand修饰的方法的返回值要保持一致

public JsonResult errorFallback() {

        return new JsonResult(1, "service error");
    }

5)如果类中所有方法都需要降级处理,在类上,使用注解

@DefaultProperties(defaultFallback = "defaultFallback",
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
            })

6)超时处理:

类上:
@DefaultProperties(defaultFallback = "defaultFallback",
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
            })

方法上:
@HystrixCommand(fallbackMethod = "errorFallback",
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000")
//            })

7)断路器配置

@HystrixCommand(commandProperties = {
            //设置断路器生效,默认配置
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            //一个统计窗口内熔断触发的最小个数,本例中5/10s
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"),
            //熔断5秒后去尝试请求
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),
            //失败率达到30百分比后熔断
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "30")})

3 feign中处理

开启feign对hystrix的支持

feign:
  hystrix:
    enabled: true  # 启用hystrix

@FeignClient中设置fallback属性,它的值是容错处理的类,该类要实现@FeignClient修饰的接口

@FeignClient(value = "MICRO-BANK", fallback = FeignServiceError.class)
public interface FeignService {

    // 和服务提供者的的方法保持一致即可,传参时,注意@RequestParam
    @RequestMapping("/balance.do")
    public JsonResult balance(@RequestParam("bankCode") String bankCode);
}

容错类

@Component
public class FeignServiceError implements FeignService {
    @Override
    public JsonResult balance(String bankCode) {
        return new JsonResult(401, "feign hystrix");
    }
}

4 hystrix dashboard

Hystrix dashboard用于提供微服务调用状态的监控信息,用于监控Hystrix的各项指标信息,通过Hystrix Dashboard反馈的实时信息,可以帮助我们快速发现系统中存在的问题

1)导入jar,需要结合spring-boot-actuator模块一起使用。

<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>

2)启动类上增加注解@EnableHystrixDashboard

3)yml中增加配置,暴露访问的端点

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

4)启动应用,查看可视化页面地址 http://localhost:8010/hystrix

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L26xxVWL-1576816067133)(cloudpic\6.png)]

5)输入监控的地址,监控地址在主页面上可以看到模板

http://localhost:8010/actuator/hystrix.stream

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7v0JgfIS-1576816067134)(cloudpic\7.png)]

点击按钮,进入监控页面,默认断路器没有打开(closed),修改代码,使服务报错,根据配置,达到一定比例,会显示open状态,过一会儿不操作,变为closed状态。页面中很多不同颜色的0,他们表示的意义,通过红框圈起内容可以明显看出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ApDfZ7uy-1576816067134)(cloudpic\8.png)]

七 config

目前SpringCloud Config的使用主要是通过Git/SVN方式做一个配置中心,然后每个服务从其中获取自身配置所需的参数。

1 config server

创建新的模块

导入jar

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

配置

spring:
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/renr1981/springcloud-config.git
          # Git仓库如果是私有仓库需要填写用户名密码,示例是公开仓库,所以不配置密码。
          username: 
          password: 

          # git上,配置文件所在路径
#          search-paths:
          # 拉取的文件放置位置
#          basedir:

启动应用,输入如下形式地址,都可以返回一些默认信息

http://localhost:5001/application/dev
http://localhost:5001/application/dev.properties
http://localhost:5001/application/dev.yml
http://localhost:5001/application-dev/dev
http://localhost:5001/application-abc/dev

文件的命名规则,和访问配置文件地址规则:

注意:application表示应用名,要和需要配置文件的应用名保持一致

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

它们都可以映射到对应的配置文件{application}-{profile}.properties,其中{label}为具体的分支,默认为master;

2 config client

导入jar

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

修改配置文件名为bootstrap.yml

先找到注册中心,再找到配置中心,所以配置中需要有注册中心的地址

server:
  port: 7001

spring:
  application:
    name: micro-bank
  cloud:
      config:
      # 分支名
        label: master
        # 和配置文件的后面保持一致
        profile: dev
        # 配置服务器地址(方案1)
        #uri: http://localhost:5001/
        # 配置为自动发现配置服务器(方案2)
        discovery:
          enabled: true
          serviceId: micro-config

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

在gitee的服务器,增加配置文件micro-bank-dev.yml:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/bank1905?serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      max-active: 20
      initial-size: 5

mybatis:
  type-aliases-package: com.rr.micro_bank.entity
  mapper-locations: classpath:mapper/*.xml

pagehelper:
    helperDialect: mysql

3 刷新配置

假如,修改了仓库中的配置文件,config的服务端,可以直接获取最新的数据,但是config的客户端,无法获取。如果想要获取,就要重启服务,很麻烦,这个时候,可以针对客户端,进行手动刷新获取最新配置

客户端导jar

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

客户端配置中增加:

#只暴露refresh,可以暴露所有:'*'
management:
  endpoints:
    web:
      exposure:
        include: refresh

在使用配置的控制器类上使用@RefreshScope注解,访问资源http://localhost:7001/haha,返回信息

@RestController
@RefreshScope
public class TestConfigController {

    @Value("${user.name}")
    private String name;

    @RequestMapping("/haha")
    public String haha(){
        return name;
    }
}

在仓库中修改内容,再次访问http://localhost:7001/haha,获取的还是原来的内容

然后,以post方式,发送http://localhost:7001/actuator/refresh(可以通过postman发送)

再次访问http://localhost:7001/haha,可以获取最新数据

安装gitee插件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pHfjJBXZ-1576816067134)(cloudpic\9.png)]

配置gitee信息

八 bus

消息总线

如果很多客户端,都用到一些配置,仓库中修改后,每个客户端都采用上面的方案进行刷新,很麻烦,这时,可以使用消息总线,给所有客户端更新配置

1 安装rabbitmq

可以使用docker安装

2 config server和client中引入jar

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>

3 config-server和client中,修改配置文件:

spring: 
  cloud: 
    bus:
      enabled: true
  rabbitmq:
    host: 106.12.48.175
    port: 5672
    username: guest
    password: guest

4 config server中还需要增加配置

#暴露端点 配置中心担任调用/bus-refresh的任务
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh

5 发送post请求,动态获取配置

http://localhost:5001/actuator/bus-refresh

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值