SpringCloud+Eureka+Nacos使用和扩展
SpringCloud
服务远程调用
消费者和生产者
服务生产者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
-
服务调用关系
-
服务提供者:暴露接口给其它微服务调用
-
服务消费者:调用其它微服务提供的接口
-
提供者与消费者角色其实是相对的
-
一个服务既可以是提供者也可以是消费者
Eureka注册中心
作用
- 消费者如何获取服务提供者具体信息
- 服务提供者启动时向eureka注册自己的信息eureka保存这些信息
- 消费者根据服务名称向eureka拉取提供者信息
- 如何有多个服务提供者,消费者该如何选择
- 服务消费者利用负载均衡算法,从服务器从挑一个
- 消费者如何感知提供者健康状态
- 服务提供者会每隔30秒向
EurekaServer
发送心跳请求,报告健康状态eureka会更新记录服务列表信息,心跳不正常会被剔除 - 消费者就可以拉取到最新的信息
- 服务提供者会每隔30秒向
服务注册
第一步
在pom.xml
文件夹中引入依赖
服务端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
第二步
配置eureka
在appliation.yml
文件中配置,因为eureka本身也是一个服务所以会将自己注册。
打开下面所配置的网址:http://localhost:1086/
server:
port: 1086
spring:
application:
name: eureka-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:1086/eureka
之后将每个服务都按上面方法都配置一遍,如果是客户端,需要引入的依赖不同,在上面也发过了。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
第三步
测试注册多个服务
之后将本地的服务重新加载一遍,如果需要注册多个,可以将服务复制;如果服务这个服务,但是这个服务已经启动会报错:提示端口已经被使用,所以启动时需要修改端口号。
方法如下。
右击服务
在这里需要配置VMoption
但是在新版的界面中没有,需要手动添加。
之后在页面中会看到这样的。在输入框中输入
取一个不冲突的端口号。
在未启动项目中运行。
运行完成后是这样的。
服务发现
需要在启动类上加上@LoadBalanced
之后在地址栏上加上配置文件中的名字user-service
负载均衡
配置负载均衡规则
通过定义IRule
实现负载均衡规则,有两种实现方式。
1、代码方式:在order-service中的OrderApplication
类中,定义新的Rule:
@Bean
public IRule randomRule() {
return new RandomRule();// 配置随机规则
}
2、在oder-service
的application.yml
文件中,添加新的配置也可以修改规则:
需要将原有的注释掉
user-service: # 给某个微服务配置负载均衡规则,这里是userservice服务
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
饥饿加载
Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。
而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients:
- user-service # 服务名称
- xx-service # 如果有其它这样写即可
- Ribbon负载均衡规则
- 规则接口是IRule
- 默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询
- 负载均衡自定义方式
- 负载均衡自定义方式
- 配置方式:直观,方便,无需重新打包发布,但是无法做全局配置
- 饥饿加载
- 开启饥饿加载
- 指定饥饿加载的微服务名称
Nacos
安装Nacos
使用docker安装
拉取镜像
docker pull nacos/nacos-server
创建容器
docker run --name nacos -e MODE=standalone -p 8848:8848 -p 9848:9848 -d nacos/nacos-server
打开地址http://192.168.2.82:8848/nacos,后面一定要加nacos
否则会出现403
Nacos的依赖
父工程
现在父工程中引入这个依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
客户端
将eureka依赖注释掉,将eureka配置注释
<!-- nacos客户端依赖包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
在需要的服务中引入配置
server-addr: IP地址:8848
spring:
application:
name: order-service
cloud:
nacos:
server-addr: 192.168.2.82:8848
服务分级存储模型
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高。
本地集群不可访问时,再去访问其它集群
一个服务可以包含多个集群,如杭州、上海,每个集群下可以有多个实例,形成分级模型。
微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。
配置集群
spring:
application:
name: user-service
cloud:
nacos:
server-addr: 192.168.2.82:8848
discovery:
cluster-name: HZ
当启动这两个服务的时候;此时配置文件中集群名字为HZ
所以启动后,集群分组为HZ
之后将配置文件修改为SH
此时启动后集群分组为SH
千万别将另外两个服务停了,如果停了另外两个就会重新读取配置文件,集群分组就变成SH
了。
点击详情
可以看到集群分组
负载均衡
修改负载均衡规则,将原有的规则替换
user-service: # 给某个微服务配置负载均衡规则,这里是userservice服务
ribbon:
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则 # 负载均衡规则
当访问接口时会优先选择名字相同的集群,如这里的配置中的HZ
,也就是本地集群,如果服务挂了才会访问其它的服务。
假设我们将本地的HZ
集群停机。会看警告信息。这是才会访问远程的集群。
权重设置
在nacos
中也可以做权重管理,当权重为1时是全部都可以访问的。
如果调到0
则不会向这个服务发起请求。所以一般在升级服务器时会会用到这点。
当调到0
时这时可以对服务进行升级,或者这台机器性能较差让它受到少量的请求,又或者当升级完成将权重设为0.1
放进来少量的用户进行访问。
因此,Nacos
提供了权重配置来控制访问频率,权重越大则访问频率越高。
环境隔离
配置命名空间
设置命名空间
三个选项只需要填写 两个即可。
之后就会在服务列表中看到
将服务移到命名空间下
要想把服务移动到命名空间下,需要在代码中修改。
移动到命名空间下,需要把命名空间的ID配置过去。
只需要在配置文件中加上这样。
之后就可以在dev中看到
Nacos与eureka的共同点
都支持服务注册和服务拉取
都支持服务提供者心跳方式做健康检测
Nacos与Eureka的区别
Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
临时实例心跳不正常会被剔除,非临时实例则不会被剔除
Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
微服务拉取
1、引入nacos-config依赖
首先,在user-service服务中,引入nacos-config的客户端依赖:
<!--nacos配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、添加bootstrap.yaml
spring:
application:
name: user-service # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: 192.168.2.82:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
如果无法读取需要加上namespace
namespace: 5d7b6c65-7ab8-440e-b580-6f060613913a # 你的命名空间
完善代码
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: 192.168.2.82:8848
config:
file-extension: yaml
namespace: 5d7b6c65-7ab8-440e-b580-6f060613913a # 你的命名空间
Data id
格式为
服务名称-开发环境.file-extension
name-active.file-extension
3、读取nacos配置
在浏览器中
验证读取到配置文件
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
完善代码
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
}
配置热更新
方式一
在@Value注入的变量所在类上添加注解@RefreshScope
:
之后在配置文件中修改
验证热更新
第一次请求时
第二次请求时
方式二
使用另一种依赖注入方式,单独创建一个配置文件
将之前的代码注释掉,并引入新的依赖(配置文件中的),重启服务器即可看到效果。
这样的操作也可以实现热更新
配置共享
在浏览器中新建服务,这个服务要不带后缀的,比如dev
,test
等
创建后在这个公共配置中写上配置内容
之后在配置文件中加上,以方便读取配置文件的内容
之后使用控制器返回,读取到的内容
调试接口
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!