spring cloud 快速开始 之 nacos篇 (起始篇)

技术架构
-
Springboot
-
Spring cloud alibaba Nacos 注册中心、配置中心,spring cloud 快速开始 之 nacos 篇
-
Spring cloud Openfeign 远程调用,spring cloud 快速开始 之 openfeign 篇
-
Spring cloud alibaba sentinel 服务熔断,spring cloud 快速开始 之 sentinel 篇
-
Spring cloud gateway 网关,spring cloud 快速开始 之 gateway 篇
-
Spring cloud alibaba seata 分布式事务, spring cloud 快速开始 之 seata 篇
nacos篇
安装Nacos
官网:https://nacos.io/zh-cn/docs/v2/quickstart/quick-start.html
Docker 安装:
docker run -d -p 8848:8848 -p 9848:9848 -e MODE=standalone --name nacos nacos/nacos-server:v2.4.3
参数说明:
run 表示运行
-d 表示后台运行
-p 表示端口映射,在nacos内部需要使用8848和9848两个端口,物理机端口:docker虚拟机端口
-e 表示环境设置 MODE 表示nacos的模式,standalone 表示单机模式
--name 表示nacos在docker中显示的名字
后面是docker下载之后的nacos镜像和版本
Springboot整合nacos
1、引入依赖,根据前面的版本适配情况进行引入
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2、设置配置信息
server:
port: 7700
spring:
application:
# 微服务的名称,这个很重要,相当于在nacos中的id,很多远程调用都需要使用这个微服务的名称
name: cloud-song
cloud:
nacos:
# nacos地址
server-addr: 10.0.0.100:8848
# 发现中心配置
discovery:
# 默认是public
namespace: CloudMusic
# 默认就是default,建议不修改,可以不写
group: DEFAULT_GROUP
3、配置启动类
在入口函数中添加注解允许发现客户端,启动服务
// springboot应用
@SpringBootApplication
// 允许发现
@EnableDiscoveryClient
4、服务注册发现
进入nacos地址:http://10.0.0.100:8848/nacos
用户名和密码都是nacos
进入之后在服务管理中的服务列表里,如果微服务启动,则在列表中出现
其中服务名就是配置文件中的application.name
5、通过复制配置文件生成多个相同的微服务,以service-product为例,这是仿照相同的微服务在不同应用中部署
a) 点击需要复制的微服务,右键打开菜单并选择copy configuration
b) 修改配置,包括Name,和端口号,这端口号可以点击Build and run 右边的modify Options,选择program arguments
然后在下面会出现输入框,输入设置端口号
然后点击OK即可创建出productApp的微服务
所有微服务运行之后,在nacos的服务列表中都有显示
nacos的使用之基础篇,获取所有微服务的信息
1、发现务客户端的使用,通过这个客户端可以获取所有微服务的IP地址和端口号,那么有了地址就可以远程访问了
// 发现客户端
@Autowired
private DiscoveryClient discoveryClient;
// 通过调用方法获取微服务的名称、主机地址和端口号
@Test
public void discoveryClientTest(){
for (String service: discoveryClient.getServices()){
log.info("服务名称");
log.info("service => "+service);
log.info("服务的IP地址以及端口");
List<ServiceInstance> instances = discoveryClient.getInstances(service);
for(ServiceInstance instance:instances){
log.info("ip => "+instance.getHost());
log.info("port => "+instance.getPort());
}
}
}
运行结果:
server-name只有一个,但是微服务的IP地址和端口号有多个,对应nacos中的有几个实体
2、发起第一个远程调用
假设Order微服务向product微服务发起远程访问,且product的远程地址为:http://127.0.0.1:9892/product/{id}
// 定义获取product的controller
@RestController
public class ProductController {
//获取商品
@GetMapping("/product/{id}")
public Product getProduct(@PathVariable("id") String id){
// 访问数据库并返回结果,这里是伪代码
Product product = new Product(id, "macbook19", 499900, 10);
return product;
}
}
Order向product发起访问的步骤:
-
通过微服务名称获取微服务实例对象
-
通过实例对象获取微服务的IP和端口号
-
通过整合协议、IP,端口号,接口路径生成访问路径
-
通过resTemplate进行访问
private Product getProductFromRemote(String id){
// 获取到商品服务所作的所有机器IP和端口
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
// 选择实例对象列表的第一个(还没涉及到负载均衡)
ServiceInstance instance = instances.get(0);
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/product/"+id;
// spring 提供的组件,线程安全的,可以在配置类生成bean,之后可自动注入
Product forObject = restTemplate.getForObject(url, Product.class);
return forObject;
}
3、负载均衡方式
3.1、代码方式
要实现负载均衡需要导入负载均衡器的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
之后就可以使用了
实例代码如下
// 注入依赖
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
// 远程调用方法
private Product getProductFrmRemoteByBalancer(String id){
// 在2个实例微服务中选择一个
ServiceInstance instance = loadBalancerClient.choose("service-product");
// 拼接访问地址
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/product/"+id;
// 发起远程访问
Product forObject = restTemplate.getForObject(url, Product.class);
return forObject;
}
3.2、注解模式
只需要在restTemplate的Bean中添加注解即可
修改远程调用
private Product getProductFrmRemoteByAnnotation(String id){
String url = "http://service-product/product"+id;
// 上面的URL会动态替换为IP:port
Product forObject = restTemplate.getForObject(url, Product.class);
return forObject;
}
需要注意:轮询方式
3.3 Q&A
1、注册中心宕机了,远程调用还能够成功?
在注册中心没宕机前如果申请过远程调用,那么微服务实例对象就会有微服务访问地址的缓存列表。
那么在基于其他微服务还正常的情况下,发送远程调用的微服务依然能够进行远程调用,只是地址列表不能与注册中心实时同步。
相反的,如果注册中心宕机了,需要访问的微服务也宕机了,那远程访问就不能够成功。
Nacos使用之基础篇,配置中心
通过nacos设置配置文件可以做到无需重启微服务即可更新配置文件
1、添加依赖
<!--管理中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、修改application.yml
spring:
application:
name: service-order
cloud:
nacos:
server-addr: 10.0.0.100:8848
# nacos 配置中心
config:
import: nacos:service-order.yaml
值得注意:service-order.yaml 这属性值在nacos中会用到
3、Nacos主页配置
在nacos主页中找到配置管理中的配置列表,并点击创建配置
编辑配置
上面提及到的service-order.yaml就是Data ID
然后配置格式选择相应的,如果前面写的是service-order.properties,那就选择配置格式为Properties
配置内容则按需写入。
然后发布
之后重启order微服务
最后一行提示了正在监听nacos配置文件
4、配置中心的配置内容的使用
方式1:@Value()
使用@Vaule的方式:
这不能自动刷新,需要在类中添加额外的注解:
// 自动刷新功能
@RefreshScope
@RestController
public class OrderController {
方式2:@ConfigrationProperties()
Nacos使用之基础篇,配置隔离
基础版
为了适配不同的生产环境,nacos通过namespace,group,dataId 对不同的环境进行隔离,如:
-
开发环境 develop
-
测试环境 test
-
生产环境 product
-
不同的微服务使用group进行隔离
-
不同的配置使用dataId
示例
如上图所示,用group作为微服务的隔离,dataID 作为配置的分类,比如数据库,redis等的配置
升级版
说明:
-
---
下面的配置可以提取到外面去的,但命名有要求,on-profile中的dev 等价于 application-dev.yaml -
---
下面配置从nacos在开发环境中需要导入的配置,通过上面的active进行选择