1)能够理解微服务架构的特点
缺点:1.消费方需要手动添加提供方地址,提供方地址改变时,不易管理
2.不易实现负载均衡
2)服务发现中心方法
服务发现就是服务消费方通过服务发现中心智能发现服务提供方,从而进行远程调用的过程。
(1 )在每个服务启动时会向服务发现中心上报自己的网络位置。这样,在服务发现中心内部会形成一个服务注册表,服务注册表是服务发现的核心部分,是包含所有服务实例的网络地址的数据库。
(2)服务发现客户端会定期从服务发现中心同步服务注册表,并缓存在客户端
( 3 )当需要对某服务进行请求时,服务实例通过该注册表,定位目标服务网络地址。若目标服务存在多个网络地址,则使用负载均衡算法从多个服务实例中选择出一个,然后发出请求。
3 )能够说出Nacos的功能
Nacos是阿里的一个开源产品,它是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案。
官网:https://nacos.io/
主流注册中心产品:
Nacos |
Eureka |
Consul |
CoreDNS |
Zookeeper |
|
一致性协议 |
CP+AP |
AP |
CP |
— |
CP |
健康检查 |
TCP/HTTP/MYSQL/Client Beat |
Client Beat |
TCP/HTTP/gRPC/Cmd |
— |
Keep Alive |
负载均衡策略 |
权重/ |
Ribbon |
Fabio |
RoundRobin |
— |
雪崩保护 |
有 |
有 |
无 |
无 |
无 |
自动注销实例 |
支持 |
支持 |
不支持 |
不支持 |
支持 |
访问协议 |
HTTP/DNS |
HTTP |
HTTP/DNS |
DNS |
TCP |
监听支持 |
支持 |
支持 |
支持 |
不支持 |
支持 |
多数据中心 |
支持 |
支持 |
支持 |
不支持 |
不支持 |
跨注册中心同步 |
支持 |
不支持 |
支持 |
不支持 |
不支持 |
SpringCloud集成 |
支持 |
支持 |
支持 |
不支持 |
不支持 |
Dubbo集成 |
支持 |
不支持 |
不支持 |
不支持 |
支持 |
K8S集成 |
支持 |
不支持 |
支持 |
支持 |
不支持 |
Nacos主要提供以下四大功能:
1.服务发现与服务健康检查*
Nacos使服务更容易注册,并通过DNS或HTTP接口发现其他服务,Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求。
2.动态配置管理
动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时重新部署应用程序,这使配置的更改更加高效和灵活。
3.动态DNS服务
Nacos提供基于DNS协议的服务发现能力,旨在支持异构语言的服务发现,支持将注册在Nacos上的服务以域名的方式暴露端点,让三方应用方便的查阅及发现。
4.服务和元数据管理
Nacos能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略。
4 )掌握Nacos的安装方法
安装Nacos Server (相当于一个服务端)
Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:
您可以从 最新稳定版本 下载 nacos-server-$version.zip 包。
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:
bash startup.sh -m standalone
启动命令(standalone代表着单机模式运行,非集群模式):
startup.cmd -m standalone
nacos有一个默认数据库,可以更改为mysql
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=youdontknow
2.3.1测试环境
Spring Cloud是一套微服务开发框架集合,包括微服务开发的方方页面,Spring Cloud是一套微服务开发的标准,集成了很多优秀的开源框架,比如有名的Netflix公司的众多项目。
Spring Cloud项目地址: https://spring.io/projects/spring-cloud
本测试环境采用阿里开源的Spring Cloud Alibaba微服务开发框架,Spring Cloud Alibaba是阿里巴巴公司基于Spring Cloud标准实现一套微服务开发框架集合,它和Netflix一样都是Spring Cloud微服务开发实现方案。
Spring Cloud Alibaba项目地址: https://github.com/alibaba/spring-cloud-alibaba
通过Spring Cloud Alibaba实现解决︰
2、服务消费方通过负载均衡获取服务地址
6 )掌握Dubbo服务发现开发方法
父工程引入springcloud和springcloud alibaba依赖
org.springframework.cloud
spring-cloud-dependencies
Greenwich.RELEASE
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.1.0.RELEASE
pom
import
1.服务注册
在服务提供方中
pom文件中添加依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
在服务提供方的application.yml配置服务发现的服务名和服务中心的地址
spring:
application:
name: nacos-restful-provider # 服务名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 服务发现中心的地址
启动服务提供者服务,自动注册到了服务中心nacos中
2.服务发现
在服务消费方客户端中操作
pom文件中添加依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
在服务提供方的application.yml配置服务发现的服务名和服务中心的地址
spring:
application:
name: nacos-restful-consumer # 服务名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 服务发现中心的地址
通过负载均衡发现服务nacos-restful-provider
在controller中
//指定服务名
String serviceId = "nacos-restful-provider";
//通过负载均衡发现地址,流程是从服务发现中心拿nacos-restful-provider服务的列表,通过负载均衡算法获取一个地址
@Autowired
LoadBalancerClient loadBalancerClient;
@GetMapping("/service2")
public String service2(){
//远程调用
RestTemplate restTemplate = new RestTemplate();
//发现一个地址
ServiceInstance serviceInstance = loadBalancerClient.choose(serviceId);
//获取一个http://开头的地址,包括ip和端口
URI uri = serviceInstance.getUri();
String result = restTemplate.getForObject(uri + "/service", String.class);
System.out.println(result);
return "consumer invoke "+result;
}
通过浏览器远程调用服务
在nacos也可以看到消费方也注册到服务中心了
负载均衡
负载均衡就是将用户请求(流量)通过一定的策略,分摊在多个服务实例上执行,它是系统处理高并发、缓解网络压力和进行服务端扩容的重要手段之一。它分为服务端负载均衡和客户端负载均衡。
上边使用的LoadBalancerClient就是一个客户端负载均衡器,具体使用的是Ribbon客户端负载均衡器。Ribbon在发送请求前通过负载均衡算法选择一个服务实例,然后进行访问,这是客户端负载均衡。即在客户端就进行负载均衡的分配。
Ribbon是一个客户端负载均衡器,它的责任是从一组实例列表中挑选合适的实例,如何挑选?取决于负载均衡策略。默认使用RoundRobinRul(默认):轮询。
Ribbon核心组件IRule是负载均衡策略接口,它有如下实现:
RoundRobinRul(默认):轮询,即按一定的顺序轮换获取实例的地址。
RandomRule:随机,即以随机的方式获取实例的地址。
AvailabilityFilteringRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,以及并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问;
WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快,服务权重越大,被选中的机率越高;
刚启动时,如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够时,会切换到WeightedResponseTimeRule
RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败,则在指定时间内会进行重试,获取可用的服务;
BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务;
ZoneAwoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器;
IntelliJ 开启spring boot多实例方法
复制实例
修改端口-Dserver.port=8180
自定义负载均衡策略
在服务消费方中application.yml文件中配置
nacos-restful-provider: # 服务名
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 某策略包路径
7 )理解Nacos服务发现的数据模型
8 )能够掌握Nacos配置管理方法
9)掌握Nacos扩展配置方法
dubbo服务发现
Dubbo是阿里巴巴公司开源的RPC框架,在国内有着非常大的用户群体,但是其微服务开发组件相对SpringCloud来说并不那么完善。
Spring Cloud Alibaba微服务开发框架集成了Dubbo,可实现微服务对外暴露Dubbo协议的接口,Dubbo协议相比RESTful协议速度更快。
RPC ∶RPC是远程过程调用(Remote Procedure Call )的缩写形式,调用RPC远程方法就像调用本地方法一样,非常方便。
1.先创建两个工程,一个api工程,一个api接口实现工程
为啥要分开api和api接口实现呢?
因为要方便后续要调用服务的人,只要调用服务的人把api依赖安装即可调用api实现服务了。
api实现类(注意@Service注解是dubbo包的注解,才会被扫描到)
package icu.weizhan.microservice.service2.service;
import icu.weizhan.microservice.service2.api.Service2Api;
import org.apache.dubbo.config.annotation.Service;
@Service
public class Service2ApiImpl implements Service2Api {
@Override
public String dubboService2() {
return "dubboService2";
}
}
把服务注册到注册中心
创建bootstrap.yml文件,写入:
server:
port: 56040 # 启动端口 命令行注入
spring:
application:
name: dubbo-service2 # 服务名称
main:
allow-bean-definition-overriding: true # Spring Boot 2.1 需要设定
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
dubbo:
scan:
# dubbo 服务扫描基准包
base-packages: icu.weizhan.microservice.service2.service
protocol:
# dubbo 协议
name: dubbo
# dubbo 协议端口
port: 20891
registry:
address: nacos://127.0.0.1:8848
application:
qos-enable: false # dobbo 运维服务是否开启
consumer:
check: false # 启动时是否检查依赖的服务
启动后
远程调用dubbo远程服务
引入依赖
icu.weizhan.nacos
service2-api
1.0-SNAPSHOT
com.alibaba.cloud
spring-cloud-starter-dubbo
调用远程服务(
org.apache.dubbo.config.annotation.Reference;
自动注入远程服务
)
@Reference
private Service2Api service2Api;
@GetMapping("/service3")
public String service3(){
//远程调用service2
String s = service2Api.dubboService2();
return "consumer invoke | " + s;
}
命名空间隔离
当不同环境注册到同一个服务中心可能会服务名冲突
解决:不同环境创建不同的命名空间
创建命名空间
设置服务放在那个空间下
spring:
application:
name: nacos-restful-consumer # 服务名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 服务发现中心的地址
namespace: 1cf3e811-a9e4-4a91-bfd8-5d166119ad59 # 命名空间id
nacos配置管理
配置中心
在微服务架构中,当系统从一个单体应用,被拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移(分割),这样配置就分散了,不仅如此,分散中还包含着冗余,如下图: 在微服务架构中,当系统从一个单体应用,被拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移(分割),这样配置就分散了,不仅如此,分散中还包含着冗余。
配置中心将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去管理配置。 下图显示了配置中心的功能,配置中心将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去管理配置.
1.发布配置
新建配置
2.获取配置
引入依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
设置配置中心地址
spring:
application:
name: nacos-restful-consumer # 服务名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 服务发现中心的地址
config:
server-addr: 127.0.0.1:8848 # 配置中心中心的地址
file-extension: yaml # 文件扩展名
注意:要使用配置中心,要在bootstrap.yml中来配置,bootstrap.yml配置文件的加载顺序要比application.yml要优先,bootstrap.yml是在系统启动时加载,因为系统启动后再加载配置中心就没有意义了
方法一:通过spring的@Value注解
@Value("${common.name}")
private String common_name;
@GetMapping("/config")
public String config(){
return common_name;
}
注意:这个方法如果修改配置不能及时获取修改后的配置
通过方法二可以解决这个问题
方法二(ConfigurableApplicationContext对象)可以动态获取配置
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping("/config")
public String config(){
return applicationContext.getEnvironment().getProperty("common.name");
}
扩展配置(如抽取公用配置)
主配置比扩展配置优先级高
spring:
application:
name: nacos-restful-consumer # 服务名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 服务发现中心的地址
config:
server-addr: 127.0.0.1:8848 # 配置中心中心的地址
file-extension: yaml # 文件扩展名 ,application.name+file-extension 找到指定文件名的文件
ext-config[0]:
data-id: ext-config-common.yaml
group: COMMON_GROUP
refresh: true
ext-config[1]:
data-id: ext-config-common2.yaml
group: COMMON_GROUP
refresh: true