1、微服务的注册中心
注册中心可以说是微服务架构中的"通讯录",它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其他服务时,就在这里找到服务的地址,进行调用。
2、 注册中心的主要作用
1.服务发现
服务注册/反注册:保存服务提供者和服务调⽤者的信息
服务订阅/取消订阅:服务调⽤者订阅服务提供者的信息,最好有实时推送的功能
服务路由(可选):具有筛选整合服务提供者的能⼒。
2.服务配置
配置订阅:服务提供者和服务调用者订阅微服务相关的配置
配置下发:主动将配置推送给服务提供者和服务调用者
3.服务健康检测
检测服务提供着的健康情况
3、常见的注册中心
Zookeeper
zookeeper它是⼀个分布式服务框架,是Apache Hadoop 的⼀个⼦项⽬,它主要是⽤来解决分布式应 ⽤中经常遇到的⼀些数据管理问题,如:统⼀命名服务、状态同步服务、集群管理、分布式应⽤配置项 的管理等。简单来说zookeeper=⽂件系统+监听通知机制。
Eureka
Eureka是在Java语⾔上,基于Restful Api开发的服务注册与发现组件,Springcloud Netflix中的重要组 件
Consul
Consul是由HashiCorp基于Go语⾔开发的⽀持多数据中⼼分布式⾼可⽤的服务发布和注册服务软件, 采 ⽤Raft算法保证服务的⼀致性,且⽀持健康检查。
Nacos
Nacos是⼀个更易于构建云原⽣应⽤的动态服务发现、配置管理和服务管理平台。简单来说 Nacos 就是 注册中⼼ + 配置中⼼的组合,提供简单易⽤的特性集,帮助我们解决微服务开发必会涉及到的服务注册 与发现,服务配置,服务管理等问题。 Nacos 还是 Spring Cloud Alibaba 组件之⼀,负责服务注册与 发现。
4、nacos简介
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了⼀组简单易用的特性集,帮助您快 速实现动态服务发现、服务配置、服务元数据及流量管理。 nacos的作用就是⼀个注册中心,用来管理注册上来的各个微服务
4.1、nacos实战入门
就现有的环境加入nacos,并将我们的两个微服务注册上去。
4.1.1、搭建nacos环境
第一步:安装nacos
下载地址 : https://github.com/alibaba/nac os/releases 下载 zip 格式的安装包,然后进⾏解压缩操作
第二步:启动nacos
# 切换⽬录 cd nacos/bin # 命令启动 startup.cmd -m standalone 或者直接双击 startup.cmd 运⾏
第三步:访问nacos
打开浏览器输入 http://localhost:8848/nacos,即可访问服务, 默认密码是nacos/nacos
4.2.2、将商品微服务注册到nacos
开始修改 shop-product 模块的代码, 将其注册到nacos服务上
1 在pom.xml中添加nacos的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2 在主类上添加@EnableDiscoveryClient注解
3 在application.yml中添加nacos服务的地址
spring:
application:
name: service-product #该服务在注册中心的id
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #nacos端口号
4 启动服务,观察nacos的控制⾯板中是否有注册上来的商品微服务
2.2.3、将订单微服务注册到nacos
1 在pom.xml中添加nacos的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2 在主类上添加@EnableDiscoveryClient注解
3 在application.yml中添加nacos服务的地址
spring:
application:
name: service-product #该服务在注册中心的id
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #nacos端口号
4 启动服务, 观察nacos的控制⾯板中是否有注册上来的订单微服务
5 修改Controller层, 借助DiscoveryClient实现微服务调用
@SpringBootApplication
@EnableDiscoveryClient
public class ShopOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ShopOrderApplication.class, args);
}
@Bean
public RestTemplate testTemplate(){
return new RestTemplate();
}
}
@RestController
public class UseController {
@Autowired
Useservice service;
@Autowired
DiscoveryClient discoveryClient;
@Autowired
RestTemplate restTemplate;
//下单
@RequestMapping("/order/prod/{pid}")
public Order order(@PathVariable("pid") int pid) {
ServiceInstance serviceInstance = discoveryClient.getInstances("service-product").get(0);
String url=serviceInstance.getHost()+":"+serviceInstance.getPort();
//调用商品微服务,查询商品信息
Product product =
restTemplate.getForObject("http://"+url+"/product/" + pid, Product.class);
//下单(创建订单)
Order order = new Order();
order.setUid(1);
order.setUsername("测试用户");
order.setPname(product.getPname());
order.setPprice(product.getPprice());
order.setNumber(1);
service.createOrder(order);
System.out.println(order);
return order;
}
}
3、服务调用Ribbon入门
经过以上的学习,已经实现了服务的注册和服务发现。当启动某个服务的时候,可以通过HTTP的形式 将信息注册到注册中⼼,并且可以通过SpringCloud提供的⼯具获取注册中⼼的服务列表。但是服务之间 的调⽤还存在很多的问题,如何更加⽅便的调⽤微服务,多个微服务的提供者如何选择,如何负载均衡等。
3.1、什么时Ribbon
是 Netflixfa 发布的⼀个负载均衡器,有助于控制 HTTP 和 TCP客户端⾏为。在 SpringCloud 中, Nacos⼀般配合Ribbon进⾏使⽤,Ribbon提供了客户端负载均衡的功能,Ribbon利⽤从Nacos中读取到 的服务信息,在调⽤服务节点提供的服务时,会合理的进行负载。
在SpringCloud中可以将注册中⼼和Ribbon配合使⽤,Ribbon⾃动的从注册中⼼中获取服务提供者的列 表信息,并基于内置的负载均衡算法,请求服务
3.1.1Ribbon的主要作用
( 1)服务调用基于Ribbon实现服务调用, 是通过拉取到的所有服务列表组成(服务名-请求路径的)映射关系。借助 RestTemplate 最终进行调用
( 2)负载均衡 当有多个服务提供者时,Ribbon可以根据负载均衡的算法⾃动的选择需要调用的服务地址
3.2、基于 Ribbon实现订单调用商品服务
3.2.1、坐标依赖
在springcloud提供的服务发现的jar中以及包含了Ribbon的依赖。所以这里不需要导⼊任何额外的坐标
3.2.2、工程改造
(1)服务提供者
控制台打印查询商品的信息
(2)服务消费者
在创建RestTemplate方法上添加 @LoadBalanced 注解
@SpringBootApplication
@EnableDiscoveryClient
public class ShopOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ShopOrderApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate testTemplate(){
return new RestTemplate();
}
}
通过服务名称消费使用
restTemplate .getForObject("http://商品服务名称/product/1" , Product.class);
4、服务调用Ribbon⾼级
4.1 负载均衡概述
4.1.1 什么是负载均衡
在搭建⽹站时,如果单节点的 web服务性能和可靠性都⽆法达到要求;或者是在使⽤外⽹服务时,经常 担⼼被⼈攻破,⼀不⼩⼼就会有打开外⽹端⼝的情况,通常这个时候加⼊负载均衡就能有效解决服务问 题。
负载均衡是⼀种基础的⽹络服务,其原理是通过运⾏在前⾯的负载均衡服务,按照指定的负载均衡算 法,将流量分配到后端服务集群上,从⽽为系统提供并⾏扩展的能⼒。
负载均衡的应⽤场景包括流量包、转发规则以及后端服务,由于该服务有内外⽹个例、健康检查等功 能,能够有效提供系统的安全性和可⽤性。
4.1.2 客户端负载均衡与服务端负载均衡
服务端负载均衡 先发送请求到负载均衡服务器或者软件,然后通过负载均衡算法,在多个服务器之间选择⼀个进⾏访 问;即在服务器端再进⾏负载均衡算法分配
客户端负载均衡 客户端会有⼀个服务器地址列表,在发送请求前通过负载均衡算法选择⼀个服务器,然后进⾏访问,这 是客户端负载均衡;即在客户端就进⾏负载均衡算法分配
4.2 基于Ribbon实现负载均衡
4.2.1、通过idea再启动⼀个 shop-product 微服务,设置其端⼝为8082
分别启动两次服务器验证效果,并查看两个控制台发现已轮询的⽅式调⽤了商品服务
4.2.2 负载均衡策略
Ribbon内置了多种负载均衡策略,内部负责复杂均衡的顶级接口为 com.netflix.loadbalancer.IRule ,实现⽅式如下:
- com.netflix.loadbalancer.RoundRobinRule :以轮询的⽅式进⾏负载均衡
- com.netflix.loadbalancer.RandomRule :随机策略
- com.netflix.loadbalancer.RetryRule :重试策略
- com.netflix.loadbalancer.WeightedResponseTimeRule :权重策略。会计算每个服务的权重,越 ⾼的被调⽤的可能性越⼤
- com.netflix.loadbalancer.BestAvailableRule :最佳策略。遍历所有的服务实例,过滤掉故障实 例,并返回请求数最⼩的实例返回
- com.netflix.loadbalancer.AvailabilityFilteringRule :可⽤过滤策略。过滤掉故障和请 求数超过阈 值的服务实例,再从剩下的实⼒中轮询调⽤
- ZoneAvoidanceRule: 以区域可⽤的服务器为基础进⾏服务器的选择。使⽤Zone对服务器进 ⾏分类,这个Zone可以理解为⼀个机房、⼀个机架等。⽽后再对Zone内的多个服务做轮询
⾃定义负载均衡策略
在消费者服务中主启动类中
⽅式1:定义⼀个新的IRule:(全局设置)
@Bean
public IRule randomRule(){
return new RandomRule();
}
⽅式2:在yml配置⽂件中配置:(局部设置)
service-product:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
5.Nacos配置管理
5.1 统⼀ 配置管理
当微服务部署的实例越来越多,达到数⼗、数百时,逐个修改微服务配置就会让⼈抓狂,⽽且很容易出 错。我们需要⼀种统⼀配置管理⽅案,可以集中管理所有实例的配置。
Nacos⼀⽅⾯可以将配置集中管理,另⼀⽅可以在配置变更时,及时通知微服务,实现配置的热更新。 10 在业界常⻅的服务配置中心,有下⾯这些:
- Apollo是由携程开源的分布式配置中⼼。特点有很多,⽐如:配置更新之后可以实时⽣效,⽀ 持灰度发布功能,并且能对所有的配置进⾏版本管理、操作审计等功能,提供开放平台API。 并且资料也写的很详细
- Disconf是由百度开源的分布式配置中心。它是基于Zookeeper来实现配置变更后实时通知和 ⽣效的
- SpringCloud Config这是Spring Cloud中带的配置中⼼组件。它和Spring是⽆缝集成,使⽤ 起来⾮常⽅便,并且它的配 置存储⽀持Git。不过它没有可视化的操作界⾯,配置的⽣效也不 是实时的,需要重启或去刷新。
- Nacos这是SpingCloud alibaba技术栈中的⼀个组件,前⾯我们已经使⽤它做过服务注册中 心。其实它也集成了服务配置的功能,我们可以直接使用它作为服务配置中⼼。
5.1.1 在nacos中添加配置⽂件
5.1.2 从微服务拉取配置
配置实现步骤:
1)引⼊nacos-config依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2)添加bootstrap.yaml
不能使⽤原来的application.yml作为配置⽂件,而是新建⼀个bootstrap.yml作为配置⽂件
配置⽂件优先级(由⾼到低): bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml
spring:
application:
name: service-product
cloud:
nacos:
config:
YAML
server-addr: 127.0.0.1:8848 #nacos
中⼼地址
file-extension: yaml #
配置⽂件格式
profiles:
active: dev #
环境标识,开发环境
4) 在nacos中添加配置
5.2 配置热更新
我们最终的⽬的,是修改nacos中的配置后,微服务中⽆需重启即可让配置⽣效,也就是配置热更新。 要实现配置热更新,可以使⽤两种⽅式
config:
appName: product
5.2.1.⽅式⼀
在@Value注⼊的变量所在类上添加注解@RefreshScope:
@RestController
@RefreshScope//
只需要在需要动态读取配置的类上添加此注解就可以
public class NacosConfigController {
@Value("${config.appName}")
private String appName;
@GetMapping("/nacos-config-test1")
public String nacosConfingTest1() {
return appName;
}
}
5.2.2.⽅式⼆
硬编码⽅式
@RestController
public class NacosConfigController {
@Autowired
private ConfigurableApplicationContext applicationContext;
Java
@GetMapping("/nacos-config-test2")
public String nacosConfingTest2() {
return applicationContext.getEnvironment().getProperty("config.app
Name");
}
}
5.3、配置共享
当配置越来越多的时候,我们就发现有很多配置是重复的,这时候就考虑可不可以将公共配置⽂件 提取出来
5.3.1 同服务内配置共享
实现步骤:
1. 新建⼀个以 spring.application.name 命名的配置⽂件,然后将其所有环境的公共配置放在⾥⾯
2. 新建⼀个名为service-product-test.yaml配置存放测试环境的配置
3. 新建⼀个名为service-product-dev.yaml配置存放开发环境的配置 4. 在两个环境⽂件中配置独有信息
4. 在两个环境⽂件中配置独有信息
# 多配置⼀段
config:
env: test
# 多配置⼀段
config:
env: dev
5. 添加测试⽅法
@RestController
@RefreshScope
public class NacosConfigController {
@Value("${config.env}")
private String env;
//3
同⼀微服务的不同环境下共享配置
@GetMapping("/nacos-config-test3")
public String nacosConfingTest3() {
return env;
}
}
5.3.2 不同微服务共享配置
不同服务之间实现配置共享的原理类似于⽂件引⼊,就是定义⼀个公共配置,然后在当前配置中引 ⼊
1. 在nacos中定义⼀个DataID为all-service.yaml的配置,⽤于所有微服务共享
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///shopserverTimezone=UTC
username: root
password: root
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
2. 修改bootstrap.yaml
spring:
application:
name: service-product
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 #nacos
file-extension: yaml
shared-dataids: all-service.yaml
refreshable-dataids: all-service.yaml
profiles:
active: dev
3. 启动商品微服务进⾏测试