Nacos 基本应用
Nacos 提供了 SDK 和 OpenAPI 方式来完成服务注册与发现等操作,SDK 实际上是对于 http 请求的封装。
微服务架构的电子商务平台,其中包含订单服务、商品服务和用户服务。可以使用 Nacos 作为服务注册和发现的中心,以便各个微服务可以相互发现和调用。
首先在 Nacos 中注册订单服务、商品服务和用户服务的实例。每个微服务会向 Nacos 注册自己的服务名和实例信息,包括 IP 地址和端口号。 当订单服务需要调用商品服务时,它可以通过 Nacos 的服务发现功能获取商品服务的实例列表。然后,订单服务可以根据负载均衡策略选择一个商品服务的实例进行调用。 另外当用户服务需要调用订单服务时,它也可以通过 Nacos 的服务发现功能获取订单服务的实例列表。然后用户服务可以根据负载均衡策略选择一个订单服务的实例进行调用。
通过使用 Nacos,可以实现微服务之间的动态调用和发现,提高系统的可伸缩性和可扩展性。此外 Nacos 还提供了配置管理和服务路由等功能,可以进一步优化和管理微服务架构。很明显使用 Nacos 可以简化微服务架构的管理和调用,提高系统的可靠性和可维护性。
windows 下安装简单,下载后解压到任意不包含中文内容的路径位置,在 conf/application.properties
中可以配置服务端口号,默认端口号为 8848。
bin/startup.cmd -m standalone
即可启动 nacos 服务器,参数 m 就是模式的含义,nacos 有单机和集群启动不同的模式
http://localhost:8848/nacos
即可访问服务,默认密码是 nacos/nacos
服务注册:
首先在父工程中添加 spring-cloud-alibaba 的管理依赖<dependencyManagement>
spring-cloud-alibaba-denpendencies pom import
dependencyManagement
元素提供了一种管理依赖版本号的方式。在 dependencyManagement
元素中声明所依赖的 jar 包的版本号等信息,那么所有子项目再次引入此依赖 jar 包时则无需显式的列出版本号。Maven
会沿着父子层级向上寻找拥有dependencyManagement
元素的项目,然后使用它指定的版本号。
添加客户端依赖:spring-cloud-starter-alibaba-nacos-discovery
application.yml 中添加 nacos 服务的地址 spring.cloud.nacos.discovery.server-addr=localhost:8848
,默认值实际上就是 localhost:8848
服务消费:
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
专门负责服务注册和发现的,可以通过它获取到注册到注册中心的所有服务
List<ServiceInstance> instances = discoveryClient.getInstances("nacos-service");
Random r=new Random();
ServiceInstance si=instances.get(r.nextInt(instances.size()));
String str = restTemplate.getForObject("http://" + si.getHost() + ":" + si.getPort() +
"/test/hello?name=" + name, String.class);
String url = serviceInstance.getUri().toString();
Product p=restTemplate.getForObject(url+"/product/"+pid,Product.class);
通过 restTemplate 调用商品微服务
将一个服务多次启动,在启动配置中设置端口号
对应 VM 配置:设置端口号
每个 SpringCloud 服务器启动后向注册中心注册本服务器信息,如服务别名、服务器 IP、端口号等,其他服务进行请求时先根据服务别名从注册中心获取到目标服务器 IP 和端口号,并将获取到的信息缓存到本地,然后通过本地使用 HttpClient 等技术进行远程调用。
Nacos 服务注册发现步骤
1、服务提供者将注册信息写入到 Nacos 注册中心的服务注册表中
2、服务注册中心将服务提供者的实例交给服务持有容器 Service Holder 处理,服务实例将会挂载在 ServiceHolder 的空间下
3、服务注册成功后,提供者将与服务中心维持心跳,未能及时发送心跳的服务将会被剔除
4、服务发现支持两种场景
-
消费者可以直接向注册中心发送获取某个服务实例的请求,这种情况下注册中心将返回所有可用的服务实例给消费者,但是一般不推荐这种情况
-
List<ServiceInstance> serviceInstances = discoveryClient.getInstances("hello-service");
服务的消费者向注册中心订阅某个服务,并提交一个监听器,当注册中心中服务发生变更时,监听器会收到通知,这时消费者更新本地的服务实例列表,以保证所有的服务均是可用的
服务注册
1、微服务在启动时,将自己的网络地址等信息注册到服务发现组件 nacos server 中,服务发现组件会存储这些信息。
2、各个微服务与服务发现组件使用一定机制通信,在一定的时间内发送心跳包。服务发现组件若发现与某微服务实例通信正常则保持注册状态(up 在线状态)、若长时间无法与某微服务实例通信,就会自动注销(即删除)该实例
3、服务消费者可从服务发现组件查询服务提供者的网络地址,并使用该地址调用服务提供者的接口。
4、当微服务网络地址发生变更(例如实例增减或者 IP 端口发生变化等)时,会重新注册到服务发现组件。
负载均衡 loadbalance
可以利用 DiscoveryClient 实现客户端的数据拉取和负载均衡,但是处理过程需要自行编码实现,重复编码就是一个问题。事实上编码没有这么麻烦,可以使用 Ribbon 组件或者 Springcloud loadbalance 组件实现的。
List<ServiceInstance> serviceInstances = discoveryClient.getInstances("hello-service");
Random r=new Random();
ServiceInstance instance = serviceInstances.get(r.nextInt(serviceInstances.size()));
负载均衡 Load Balance 就是将用户的请求平均的分配到多个服务上,从而达到系统的高可用,它是一种算法,可以通过该算法实现从地址列表中获取一个地址进行服务调用,LB 实现方式包含集中式(在消费者和服务提供方中间使用独立的代理方式进行负载均衡)和进程内(根据自己的请求情况做负载均衡)两种。
Nginx 服务器负载均衡,客户端所有请求都会交给 Nginx,然后 Nginx 实现转发请求,属于集中式实现负载均衡;
Ribbon 本地负载均衡,在调用微服务接口的时候,会在注册中心上获取注册信息服务列表后缓存到本地,从而在本地实现 RPC 远程服务调用,属于进程内实现负载均衡。
依赖:spring-cloud-starter-loadbalancer
,需要添加 alibaba 和 cloud
RestTemplate 的生成方法上添加@LoadBalanced 注解
@LoadBalanced 是标识注解,用于告知系统这里的请求应该通过负载均衡组件进行拦截和处理。实际上是通过实现了 ClientHttpRequestInterceptor
接口的 LoadBalancerInterceptor
实现拦截的,可以在 intercept 方法上添加断点查看源码
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate(); }
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/say")
public String say(@RequestParam(required = false) String name) {
String ss = restTemplate.getForObject("http://provider-service/hello?name={0}",
String.class, name);
ss = "{ConsumerController}---" + ss;
return ss;
}
}