文章目录

注册中心Eureka:服务搭建小结

Ribbo - 负载均衡1. 负载均衡流程2. 负载均衡策略

nacos注册中心1. 配置集群1. 创建 namespace2. 配置命名空间1. nacos添加配置文件2. 从nacos拉取配置

通过这篇文章来跟大家聊聊spring Cloud中的注册中心

想了解配置中心的地址在此

https://blog.csdn.net/weixin_44797327/article/details/134653510?spm=1001.2014.3001.5501

注册中心

需求:当一个服务提供者 Service 部署了多个实例交给 User 远程调用时:

服务消费者 User 应该调用哪个实例,如何获取其对应地址和端口?User 如何获知实例是否健康?

注册中心作用:

帮助管理服务,并帮助服务调用者选择并调用服务实时监测服务实例是否健康

Eureka:

构成: eureka-server:服务端,注册中心 记录服务信息,心跳监控

eureka-client:客户端, 服务提供者(注册到服务端,定期向服务端发送心跳)、服务消费者(从服务端拉取服务列表,基于负载均衡选择服务) 作用:

服务注册: Service实例启动后,会将自己的信息注册到 eureka服务端 服务拉取: User 根据 实例名 获取 Service 地址列表

服务搭建

配置文件:

我们需要将 eureka 注册到spring容器中,所以需要在配置文件中做相关配置。

server:

port: 8099

spring:

application:

name: eureka_server

eureka:

client:

# 配置eureka服务地址

service-url:

defaultZone: http://127.0.0.1:8099/eureka

项目启动:

为了让项目能启动 eureka,需要在启动类上加一个注解:@EnableEurekaServer

@SpringBootApplication

@EnableEurekaServer

public class ServerApplication {

public static void main(String[] args) {

SpringApplication.run(ServerApplication.class, args);

}

}

启动项目,访问地址:http://127.0.0.1:8099:

注册的服务名称就是配置文件中的名称的大写。

服务注册

在上一步,已经将 eureka-server (eureka服务中心)搭建完毕,现在就开始注册服务实例了。

注意:

无论是 服务提供者 还是 服务消费者,他们的身份都是 eureka-client

记得添加 spring-boot-starter-web 的依赖,不然会报错:Field optionalArgs in org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration required a bean of type ‘com.netflix.discovery.AbstractDiscoveryClientOptionalArgs’ that could not be found.

服务发现、服务注册统一都封装在eureka-client依赖。

需要在配置文件中配置 eureka-server 的地址。

spring:

application:

name: service_provider

eureka:

client:

service-url:

defaultZone: http://127.0.0.1:8099/eureka

启动多个实例

为了让项目能启动 eureka,需要在启动类上加一个注解:@EnableEurekaClient。

@SpringBootApplication

@EnableEurekaClient

public class ProviderApplication {

public static void main(String[] args) {

SpringApplication.run(ProviderApplication.class, args);

}

}

我们可以通过 IDEA 自带功能模仿启动多个服务实例。

打开 Service 面板

****

复制原来的 provider 启动配置

查看 eureka注册中心

服务发现

依赖导入

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

配置文件:

spring:

application:

name: service_user

server:

port: 8084

eureka:

client:

service-url:

defaultZone: http://127.0.0.1:8099/eureka

服务拉取和负载均衡

服务拉取:

修改 controller 代码,将 url 路径的 ip、端口 修改为 服务名: @RestController

@RequestMapping("user")

public class UserController {

@Autowired

private RestTemplate restTemplate;

@GetMapping("/{id}")

public Book getBookById(@PathVariable("id") Integer id) {

// String url = "http://127.0.0.1:8081/provider" + id;

String url = "http://service_provider/provider";

if (id != null) {

url = url + id;

}

Book book = restTemplate.getForObject(url, Book.class);

return book;

}

}

注册 RestTemplate 的时候加上注解 @LoadBalanced

@LoadBalanced

@Bean

public RestTemplate restTemplate() {

return new RestTemplate();

}

接口调用:

@RestController

@RequestMapping("user")

public class UserController {

@Autowired

private RestTemplate restTemplate;

@GetMapping("/{id}")

public Book getBookById(@PathVariable("id") Integer id) {

// String url = "http://127.0.0.1:8081/provider" + id;

String url = "http://PROVIDER/pro/";

if (id != null) {

url = url + id;

}

Book book = restTemplate.getForObject(url, Book.class);

return book;

}

}

访问接口:

访问报错:

解决方案:

多测试几下接口,可以发现,user一会儿调用的是 provider:8081 一会儿调用的是 provider:8082。这就是负载均衡算法选择的。

小结

eureka-server 搭建:

引入依赖:

org.springframework.cloud

spring-cloud-starter-netflix-eureka-server

启动类添加 @EnableEurekaServer配置文件配置 eureka 地址

server:

port: 8099

spring:

application:

name: server

eureka:

client:

# 配置eureka服务地址

service-url:

defaultZone: http://127.0.0.1:8099/eureka

服务注册:

引入依赖:

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

启动类添加 @EnableEurekaClient配置文件配置 eureka 地址

server:

port: 8081

spring:

application:

name: provider

eureka:

client:

# 配置eureka服务地址

service-url:

defaultZone: http://127.0.0.1:8099/eureka

服务发现:

引入依赖:

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

启动类添加 @EnableEurekaClient配置文件配置 eureka 地址

server:

port: 8089

spring:

application:

name: user

eureka:

client:

# 配置eureka服务地址

service-url:

defaultZone: http://127.0.0.1:8099/eureka

Ribbo - 负载均衡

1. 负载均衡流程

Ribbon负载均衡流程图:

http://PROVIDER/pro/4 并非真实的地址,这个需要Ribbon负载均衡去拦截,然后选择具体的服务地址。而,Ribbon就是通过 LoadBalancerInterceptor 的 intercept 方法来实现拦截请求并解析选择地址。

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {

URI originalUri = request.getURI();

String serviceName = originalUri.getHost();

Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);

return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));

}

负载均衡流程:

2. 负载均衡策略

Ribbon的负载均衡策略是由 IRule 接口来定义的。

自定义负载均衡策略:

方式一: 在user中,@Bean 注入自定义 IRule

@Bean

public IRule randomRule(){

return new RandomRule();

}

方式二: 在user,配置文件修改 IRule

provider: # 给某个微服务配置负载均衡规则,这里是userservice服务

ribbon:

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则

注意:

方式一的作用范围是:在访问任何微服务的时候,都是使用 RandomRule 负载均衡策略;

方式二的作用范围是:在访问 provider 微服务的时候才是采用 RandomRule 策略,其他的还是使用默认策略。

加载策略:

Ribbon默认采用懒加载,即会在第一次访问时才会去创建 LoadBalanceClient ,所以会在第一次请求的时候花上较长的等待时间。

可以通过配置文件更改加载策略为饿加载策略,即初始化时就创建 LoadBalanceClient ,降低第一次访问的耗时。

ribbon:

eager-load:

enabled: true # 开启饥饿加载

clients: provider # 指定饥饿加载的服务名称

nacos

概念: 服务注册中心 作用:

心跳检查: 不同于 eureka 只能 Service实例 主动发起心跳,nacos 对于非临时实例可以主动发起心跳检查 临时心跳检查异常的会被剔除出 服务地址列表

非临时心跳检查异常的不会被剔除定时推送变更: nacos 支持服务列表变更的消息推送模式,服务列表更新更及时

注册中心

引入依赖、修改配置

父工程添加 SpringCloudAlibaba 的管理依赖。

com.alibaba.cloud

spring-cloud-alibaba-dependencies

2.2.6.RELEASE

pom

import

子工程中注释掉 eureka 依赖,引入 nacos 依赖。

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

配置文件配置nacos地址:

spring:

cloud:

nacos:

server-addr: localhost:8848 # nacos服务地址

启动 user 和 provider :

注意: eureka 注册名会变成大写,nacos 不会,所以改成 nacos 之后,需要把访问地址改成小写。

请求测试:

服务分级存储模型 一个服务可以拥有多个实例,如:provider 的 8081 和 8082,如果这些实例分布于全国不同的机房,如:provider:8081 在成都机房、provider:8082 在重庆机房,Nacos就将同一机房内的实例 划分为一个集群。

即,一个服务可以拥有多个集群,一个集群中可以拥有多个实例。

微服务相互之间访问时,访问本地的速度更快,所以应该尽可能访问相同集群的实例,只有当本集群内存不够时,才去访问其他集群。

1. 配置集群

配置服务集群:

spring:

cloud:

nacos:

server-addr: localhost:8848 # nacos服务地址

discovery:

cluster-name: CD

VM Options:

-Dserver.port=8082 -Dspring.cloud.nacos.discovery.cluster-name=CQ

2. 同集群优先的负载均衡

默认的 ZoneAvoidanceRule 负载均衡策略并不能实现据同集群优先来实现负载均衡,因此Nacos中提供了一个NacosRule的实现,可以优先从同集群中挑选实例。

修改负载均衡策略:

方式一:

@Bean

public IRule nacosRule(){

return new NacosRule();

}

方式二:

provider: # 访问的服务名

ribbon:

NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则

3. 权重配置

服务器的性能之间存在差异,为了让性能能好的服务器承担更多的用户请求,Nacos提供了权重配置来控制访问率:权重越大、访问率越高。

注意: 权重为0的服务永远不会被访问。

4. 环境隔离

Nacos提供了namespace来实现环境隔离功能。

nacos中可以有多个namespacenamespace下可以有group、service等不同namespace之间相互隔离(不同namespace的服务互相不可见)

1. 创建 namespace

Nacos默认的namespace是:public

命名空间

Nacos创建命名空间流程:

2. 配置命名空间

spring:

cloud:

nacos:

discovery:

namespace: e11eb3bc-8eed-4cdd-93f0-7a6c01b85eb4 # 命名空间,填ID

spring:

cloud:

nacos:

discovery:

ephemeral: false # 设置为永久实例

3. 配置管理

Nacos不仅可以担任微服务的注册中心,还可以担任配置管理。

统一配置管理

可以使用统一配置管理来处理因为部署的微服务数量过多,配置繁杂等问题。

Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。

注意: 只把那些需要热更新的配置文件交给Nacos

1. nacos添加配置文件

Data ID: 配置文件id:服务名称-profile.后缀名 。

2. 从nacos拉取配置

spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:

引入nacos-config依赖:

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-config

添加bootstrap.yml

spring:

application:

name: user # 服务名称

profiles:

active: dev #开发环境,这里是dev

cloud:

nacos:

server-addr: localhost:8848 # Nacos地址

config:

file-extension: yaml # 文件后缀名

这里会根据spring.cloud.nacos.server-addr获取nacos地址,再根据

s

p

r

i

n

g

.

a

p

p

l

i

c

a

t

i

o

n

.

n

a

m

e

{spring.application.name}-

spring.application.name−{spring.profiles.active}.${spring.cloud.nacos.config.file-extension}作为文件id,来读取配置。

读取nacos配置

@Value("${pattern.dateformat}")

private String dateformat;

@GetMapping("now")

public String now() {

return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));

}

启动报错: org.springframework.beans.factory.BeanCreationException: Error creating bean with name xxx

解决方案:

检查 namespace,配置文件与服务要在同一个 namespace 中 名称是否拼错 升级 nacos 版本 @Value 切换为 @NacosValue

配置热更新 配置热更新: 修改nacos中的配置后,微服务中无需重启即可让配置生效。

实现方式:

方式一: 在@Value注入的变量所在类上添加注解 @RefreshScope 方式二: 使用 @ConfigurationProperties 注解代替@Value注解 在 user 服务中,添加一个类,读取patterrn.dateformat属性:

@Component

@Data

@ConfigurationProperties(prefix = "pattern")

public class PatternProperties {

private String dateformat;

}

在UserController中使用这个类代替@Value:

@Autowired

private PatternProperties patternProperties;

@GetMapping("now")

public String now() {

return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat));

}

配置共享

其实微服务启动时,会去nacos读取多个配置文件,因为nacos管理的配置文件不包含环境信息,可以被多个环境共享。

只需要取名的时候,不加上 profile 就能被共享,如下:

配置共享时的优先级:

参考链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。