过渡分布式微服务
以前的架构还是最原始阶段,官网、论坛、云平台等应用即一台服务器搞定一切。对应的web服务器、数据库、静态文件资源等,部署到一台服务器上即可。一般每秒几百请求没啥问题,结合内核参数调优、web应用性能参数调优、数据库调优,基本上能够稳定的运行。随着业务量越来越大和越重要,单体的架构模式已经无法对应大规模的应用场景。大量的web请求被堵塞,同时服务器的CPU、磁盘IO、带宽都有压力。系统功能越来越复杂,功能模块之间耦合性强相互影响。而且系统中决不能存在单点故障导致整体不可用。
所以只有垂直或是水平拆分业务系统,使其形成一个分布式的架构,利用分布式架构来冗余系统消除单点的故障,从而提高整个系统的可用性。同时分布式系统的模块重用度更高,高并发下的速度更快,扩展性更高是大型的项目必不可少的环节。
微服务
这一词源于 Martin Fowler 的 Microservices 博文,于2014年三月25日发表,简单地说,微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务
,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的RESTful API进行通信协作。
被拆分成的每一个小型服务都围绕着系统中的某一项或一些耦合度较高的业务功能进行构建,并且每个服务都维护着自身的数据存储、业务开发、自动化测试案例以及独立部署机制。由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。
SpringCloud
SpringCloud项目不同于其他 Spring 的优秀项目, 它不再是一个基础框架类, 而是一个更高层次的、 架构视角的综合性大型项目, 其目标旨在构建一套标准化的微服务解决方案, 让架构师、 开发者在使用微服务理念构建应用系统的时候, 面对各个环节的问题都可以找到相应的组件来处理。 引用网友戏称的一个比喻:Spring Cloud可以说是Spring社区为微服务架构提供的一个全家桶套餐
。 由于套餐中的组件通过一个社区进行包装与整合, 使得套餐中各个组件之间的配合变得更加和谐,这可以有效减少我们在组件的选型和整合上花费的精力,所以它可以帮助我们快速构建起基础的微服务架构系统。
特点
- 来源于 Spring,质量、稳定性、持续性都可以得到保证。
- 天然支持 Spring Boot,更加便于业务落地。
- 对于中小企业来讲,使用门槛较低。
- 与分布式系统相关的复杂性 – 包括网络问题,延迟开销,带宽问题,安全问题。
- 处理服务发现的能力 – 服务发现允许集群中的进程和服务找到彼此并进行通信。
- 解决冗余问题 – 冗余问题经常发生在分布式系统中。
- 负载平衡 – 改进跨多个计算资源(例如计算机集群,网络链接,中央处理单元)的工作负载分布。
- 减少性能问题 – 减少因各种操作开销导致的性能问题。
基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了基于NetFlix的开源组件做高度抽象封装之外,还有一些选型中立的开源组件。
SpringCloud利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,SpringCloud为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等,它们都可以用SpringBoot的开发风格做到一键启动和部署。
各组件功能
- Eureka:注册中⼼,⽤来进⾏服务的⾃动注册和发现
- Ribbon:负载均衡组件,⽤来在消费者调⽤服务时进⾏负载均衡
- OpenFeign:基于接⼝的申明式的服务调⽤客户端,让调⽤变得更简单
- Hystrix:断路器,负责服务容错
- Zuul:服务⽹关,可以进⾏服务路由、服务降级、负载均衡等
- Nacos:分布式配置中⼼以及注册中⼼
- Sentinel:服务的熔断降级,包括限流
- Seata:分布式事务
- Spring Cloud Config:分布式配置中⼼
- Spring Cloud Bus:消息总线
- Spring Cloud Stream:消息驱动能力的框架
- Spring Cloud Sleuth:分布式跟踪解决方案
Spring Cloud Alibaba
同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件(主要为Nacos、Sentinel、Dubbo、Seata)来迅速搭建分布式应用系统。
开始SpringCloud
父pom.xml
<!-- 子模块继承之后,提供作用:锁定版本 + 子modlue不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!-- spring boot 2.2.2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud Hoxton.SR1 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 2.1.0.RELEASE -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Eureka
Spring-Cloud Euraka是Spring Cloud集合中一个组件,它是对Euraka的集成,用于服务注册和发现。Eureka是Netflix中的一个开源框架。它和 zookeeper、Consul一样,都是用于服务注册管理的。
Eureka由多个instance(服务实例)组成,这些服务实例可以分为两种:Eureka Server和Eureka Client。为了便于理解,我们将Eureka client再分为Service Provider和Service Consumer。
- Eureka Server 提供服务注册和发现
- Service Provider 服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
- Service Consumer服务消费方,从Eureka获取注册服务列表,从而能够消费服务
部署Eureka Server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
启动类:
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class, args);
}
}
application.yml
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:7001/eureka/
运行后访问lhttp://ocalhost:7001/eureka 就能看到注册进Eureka的服务实例
部署Eureka Client
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
主启动加上三个注解:
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
application.yml
server:
port: 8001
spring:
application:
name: cloud-payment-service
eureka:
client:
#表示是否将自己注册进EurekaServer,默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
#defaultZone: http://localhost:7001/eureka
instance:
instance-id: payment8001
#访问路径可以显示IP地址
prefer-ip-address: true
#Eureka客户端向服务端发送信心跳时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
Provider则为数据库查询数据接口,Customer通过RestTemplate用http请求让Provider去数据库查过来自己用。
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment) {
return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
}
https://github.com/rawchen/SpringCloud
http://www.heartthinkdo.com/?p=1933
https://github.com/Netflix/eureka/wiki
CAP定理
C(Consistency):一致性
A(Availablitity):可用性
P(Partition tolerance):分区容错性
Euere是AP,高可用与可伸缩的Service发现服务,突出可用性。相对于Zookeeper而言,可能返回数据没有一致性,但是保证能够返回数据,服务是可用的。
Zookeeper是CP,分布式协同服务,突出一致性。对ZooKeeper的的每次请求都能得到一致的数据结果,但是无法保证每次访问服务可用性。如请求到来时,zookeer正在做leader选举,此时不能提供服务,即不满足A可用性。
Zookeeper
在Eureka平台中,如果某台服务器宕机,Eureka不会有类似于ZooKeeper的选举leader的过程;客户端请求会自动切换到新的Eureka节点;当宕机的服务器重新恢复后,Eureka会再次将其纳入到服务器集群管理之中;而对于它来说,所有要做的无非是同步一些新的服务注册信息而已。所以,再也不用担心有“掉队”的服务器恢复以后,会从Eureka服务器集群中剔除出去的风险了。
客户端提供者
pom.xml
<!-- SpringBoot整合zookeeper客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
application.yml
server:
port: 8004
spring:
application:
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: 192.168.0.104:2181
@EnableDiscoveryClient
./zkServer.sh start
客户端消费者
application.yml
server:
port: 80
spring:
application:
# 服务别名
name: cloud-consumer-order
cloud:
zookeeper:
# 注册到zookeeper地址
connect-string: localhost:2181
https://github.com/rawchen/SpringCloud
https://www.cnblogs.com/zgghb/p/6515062.html
http://zookeeper.apache.org/doc/current/index.html
https://blog.csdn.net/java_66666/article/details/81015302
Consul
是google开源的一个使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。服务部署简单,只有一个可运行的二进制的包。每个节点都需要运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以保证数据安全,同时保证server-leader的选举能够正确的进行。
pom.xml
<!-- SpringCloud consul-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
application.yml
server:
port: 8006
spring:
application:
name: consul-provider-payment
#consul注册中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}
@EnableDiscoveryClient
Ribbon
提供各种负载均衡算法。Ribbon核心组件IRule。
有如下几种复杂均衡算法:
com.netflix.loadbalancer.RoundRobinRule 轮询
com.netflix.loadbalancer.RandomRule 随机
com.netflix.loadbalancer.RetryRule 先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内进行重试,获取可用的服务
WeightedResponseTimeRule 对RoundRobinRule的扩展,响应速度越快的实例选择权重越多大,越容易被选择
BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例
ZoneAvoidanceRule 默认规则,复合判断server所在区域的性能和server的可用性选择服务器
替换负载均衡算法
新建MySelfRule规格类
@Configuration
public class MySelfRule {
@Bean
public IRule myRule() {
// 定义为随机
return new RoundRobinRule();
}
}
主启动加上RibbonClient
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class)
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class, args);
}
}
手写负载均衡中的轮询
MyLB.java
@Component
public class MyLB implements LoadBalancer {
private AtomicInteger atomicInteger = new AtomicInteger(0);
public final int getAndIncrement() {
int current;
int next;
do {
current = this.atomicInteger.get();
next = current >= 2147483647 ? 0 : current + 1; //Integer.MAX_VALUE 会创建多个栈
} while (!this.atomicInteger.compareAndSet(current, next));
System.out.println("****第几次访问,次数next为****: " + next);
return next;
}
//负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标
//每次服务重启后rest接口计数从1开始
@Override
public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
int index = getAndIncrement() % serviceInstances.size();
return serviceInstances.get(index);
}
}
https://github.com/rawchen/SpringCloud
https://github.com/Netflix/ribbon
OpenFeign
之前例子都是用的RestTemplate的HTTP请求工具。
OpenFeign为微服务架构下服务之间的调用提供了解决方案,OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。
pom.xml
<!-- openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
主启动:@EnableFeignClients
service
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping(value = "/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id);
}
application.yml
#设置feign客户端超时时间(OpenFeign默认支持Ribbon)
ribbon:
#建立所需时间,适用于网络状况正常情况下,两端连接所需时间
connectTimeout: 5000
#指的是建立连接后从服务器读到可用资源所用时间
ReadTimeout: 5000
https://github.com/rawchen/SpringCloud
https://github.com/OpenFeign/feign
Hystrix
雪崩效应
在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。
如果下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
CircuitBreaker熔断器
熔断器的原理很简单,如同电力过载保护器。它可以实现快速失败,如果它在一段时间内侦测到许多类似的错误,会强迫其以后的多个调用快速失败,不再访问远程服务器,从而防止应用程序不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生。熔断器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。
熔断器模式就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。 熔断器开关相互转换的逻辑如下图:
断路器机制
当在一定窗口期时间内(默认10s),请求数大于一定值(默认20次)且错误率大于一个值(默认50%)则熔断器会打开也就是跳闸,一段时间后(默认5s)进入半开状态,允许放行一个试探请求,否则不允许放行。
相关值在HystrixCommandProperties类中。
Fallback降级
对于查询操作,我们可以实现一个fallback方法,当请求后端服务出现异常的时候,可以使用fallback方法返回值,fallback方法的返回值一般是设置的默认值或者来自缓存。
资源隔离
在Hystrix中,主要通过线程池来实现资源隔离。通常在使用的时候我们会根据调用的远程服务划分出多个线程池。例如调用产品服务的Command放入A线程池,调用账户服务的Command放入B线程池。这样做的主要优点是运行环境被隔离开了。
pom.xml
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
application.yml
feign:
hystrix:
enabled: true
主启动加上@EnableHystrix,也同时加上了@EnableCircuitBreaker
PaymentHystrixService接口上的FeignClient添加fallback方法
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
@GetMapping(value = "/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping(value = "/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
PaymentFallbackService类则实现PaymentHystrixService实现降级方法
@Component
public class PaymentFallbackService implements PaymentHystrixService {
@Override
public String paymentInfo_OK(Integer id) {
return "-----PaymentFallbackService OK-----";
}
@Override
public String paymentInfo_TimeOut(Integer id) {
return "-----PaymentFallbackService Timeout-----";
}
}
超时熔断:
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
})
服务熔断:
@HystrixCommand(fallbackMethod = "paymentCircuitBreakerFallack", commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),//失败率达到多少后跳闸
})
HystrixDashboard
pom.xml
<!--hystrix dashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
主启动@EnableHystrixDashboard
微服务提供者需要spring-boot-starter-actuator的jar依赖
http://localhost:9001/hystrix
输入框输入要监控的服务,比如http://localhost:8001/hystrix.stream
延时写1000ms,标题随意,则可看到要监控的Hystrix熔断器的服务,相关参数自查。
Spring Cloud Gateway
网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。
API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。
Gateway使用的是Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。
三大核心概念
- Route(路由) - 路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如断言为true则匹配该路由
- Predicate(断言) - 参考的是Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
- Filter(过滤) - 指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
pom.xml
<!-- Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
application.yml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#匹配后提供服务的路由地址
# uri: http://localhost:8001
uri: lb://cloud-payment-service
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_route2
# uri: http://localhost:8001
uri: lb://cloud-payment-service
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
- After=2021-08-20T16:48:18.967+08:00[Asia/Shanghai] #路由断言,在这时间之后才能访问
# - Before=2021-08-20T16:48:18.967+08:00[Asia/Shanghai]
# - Between=2021-08-20T16:48:18.967+08:00[Asia/Shanghai],2021-08-20T17:48:18.967+08:00[Asia/Shanghai]
# - Cookie=username,rawchen
# - Header=X-Request-Id, \d+ #请求头要有X-Request-Id属性并且值为整数的正则表达式
# - Host=**.rawchen.com
# - Method=GET
# - Query=username, \d+ #要有参数名username并且值还要是整数才能路由
filters:
- AddRequestParameter=X-Request-Id, 1024 #过滤器工厂会在匹配的请求头加上一对该请求头
MyLogGateWayFilter.java
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("MyLogGateWayFilter: " + new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
log.info("用户名为null,非法用户");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
Spring Cloud Config
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
application.yml
可用ssh或者http的方式连接到github
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
#ssh-keygen -m PEM -t rsa -b 4096 -C "xxxxxx@qq.com" 使用此命令生成git密钥对
uri: git@github.com:rawchen/springcloud-config.git #远端仓库名
# uri: https://github.com/rawchen/springcloud-config.git #远端仓库名
#搜索目录
search-paths:
- springcloud-config
# username: rawchen
# password: xxx
#读取分支
label: main
访问http://localhost:3344/main/config-dev.yml
Config client
bootstrap.yml
server:
port: 3355
spring:
application:
name: config-client
cloud:
config:
label: main #分支名称
name: config #配置文件名称
profile: test #读取后缀名称 上述三个综合http://localhost:3344/main/config-test.yml
uri: http://localhost:3344 #配置中心的地址
Controller
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo() {
return configInfo;
}
}
访问http://localhost:3355/configInfo
多个客户端都需要调用一次api才能刷新属性config
curl -X POST "http://localhost:3355/actuator/refresh"
curl -X POST "http://localhost:3366/actuator/refresh"
SpringCloud Bus
什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个公用的消息主题,并让系统中的所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他链接在该主题行的实例都知道的消息。
基本原理
ConfigClient实例都监听MQ中的同一个topic(默认是SpringcloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到topic中,这样其它监听同一个topic的服务就能得到通知,然后去更新自身的配置。
Config配置中心服务端pom.xml
<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
application.yml
#rabbitmq相关配置 15672是web管理端的端口,5672是MQ访问的端口
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#rabbitmq相关配置,暴露bus刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
客户端bootstrap.yml
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
此时只需调用配置中心服务的刷新总线api通知其它服务:
curl -X POST "http://localhost:3344/actuator/bus-refresh"
Spring Cloud Stream
Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架。它可以基于 Spring Boot 来创建独立的、可用于生产的 Spring 应用程序。Spring Cloud Stream 为一些供应商的消息中间件产品提供了个性化的自动化配置实现,并引入了发布-订阅、消费组、分区这三个核心概念。通过使用 Spring Cloud Stream,可以有效简化开发人员对消息中间件的使用复杂度,让系统开发人员可以有更多的精力关注于核心业务逻辑的处理。但是目前 Spring Cloud Stream 只支持 RabbitMQ 和 Kafka 的自动化配置。
pom.xml
<!-- stream rabbitmq -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
application.yml
server:
port: 8801
spring:
application:
name: cloud-stream-privider
cloud:
stream:
binders: #自此处配置要绑定的rabbitmq的服务信息
defaultRabbit: #表示定义的名称,用于binding整合
type: rabbit #消息组件类型
environment: # 设置rabbitmq的相关的环境配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
bindings: #服务的整合处理
output: #这个名字是一个通道的名称
destination: studyExchange #表示要使用的exchange名称定义
content-type: application/json #设置消息类型,本次为json
binder: defaultRabbit #设置要绑定的消息服务的具体设置
group: MQGroupA
Spring Cloud Sleuth
为Spring Cloud实现了分布式跟踪解决方案。
需运行zipkin.jar服务
pom.xml
<!-- 包含了sleuth+zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
application.yml
spring:
application:
name: cloud-payment-service
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
#采样率值介于0到1之间,1则表示全部采集
probability: 1