服务生产者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
服务调用关系
服务提供者:暴露接口给其它微服务调用
服务消费者:调用其它微服务提供的接口
提供者与消费者角色其实是相对的
一个服务既可以是提供者也可以是消费者
EurekaServer
发送心跳请求,报告健康状态eureka会更新记录服务列表信息,心跳不正常会被剔除在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 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
父工程
现在父工程中引入这个依赖
<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
等
创建后在这个公共配置中写上配置内容
之后在配置文件中加上,以方便读取配置文件的内容
之后使用控制器返回,读取到的内容
调试接口