执行后的效果如图,并且不会报错:
(4)访问
在浏览器输入地址:http://127.0.0.1:8848/nacos即可访问:
默认的账号和密码都是nacos,进入后:
这里就成功进入到我们nacos的控制台了!
3.Linux下安装Nacos
Linux或者Mac安装方式与Windows类似。
(1)上传安装包,随便用什么方式上传上去, 但是要记住上传.tar.gz的那个包。
(2)移动到Linux服务器的某个目录,例如/usr/local/src目录下
(3)解压
命令解压缩安装包:
tar -xvf nacos-server-2.1.0.tar.gz
然后删除安装包:
rm -rf nacos-server-2.1.0.tar.gz
4. 服务注册到nacos
下面我们就可以用Nacos来完成服务注册和服务发现了。
不管是Eureka也好,还是Nacos也好,只要是做服务注册和服务发现,都会遵循Spring Cloud Commons的一些通用接口。那么,我们在使用Eureka或者Nacos时,我们的服务提供者和服务消费者的代码是不用做任何变化的。要改变的东西是我们要引用的依赖,以前是Eureka的依赖,现在该引用Nacos的依赖了。第二呢就是服务地址,以前我们的服务地址配的是Eureka的地址,现在改成配Nacos的地址就可以了。
总结一下就是:
Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。
主要差异在于:
依赖不同
服务地址不同
(1)引入依赖
在cloud-demo父工程的pom文件中的<dependencyManagement>中添加SpringCloudAlibaba的依赖:
<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>
然后在user-service和order-service中的pom文件中分别引入nacos-discovery依赖:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
注意:不要忘了注释掉eureka的依赖。
(2)配置nacos地址
在user-service和order-service的application.yml中添加nacos地址:
spring: cloud: nacos: server-addr: localhost:8848
这里也不要忘记把之前Eureka的配置删除掉
更改后的yml分别如下:
server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false username: root password: zc20020106 driver-class-name: com.mysql.cj.jdbc.Driver application: #服务的名称 name: userservice cloud: nacos: server-addr: localhost:8848 # nacos服务地址 mybatis: type-aliases-package: com.haiexijun.user.pojo configuration: map-underscore-to-camel-case: true logging: level: com.haiexijun: debug pattern: dateformat: MM-dd HH:mm:ss:SSS
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false username: root password: zc20020106 driver-class-name: com.mysql.cj.jdbc.Driver application: #服务的名称 name: orderservice cloud: nacos: server-addr: localhost:8848 # nacos服务地址 mybatis: type-aliases-package: com.haiexijun.user.pojo configuration: map-underscore-to-camel-case: true logging: level: com.haiexijun: debug pattern: dateformat: MM-dd HH:mm:ss:SSS
(3)重启所有服务
打开nacos的控制台,可以查看到服务列表了。
我们点开详情,会有更详细的服务信息:
5. 服务分级存储模型
你光听名字是不是觉得服务分级存储模型很高级啊,但其实我们已经接触过这样的分级概念了。
之前,我们有服务的概念,我们提供用户查询的user-service,还有提供订单查询的order-service,他们都叫服务。然后我们user-service还部署了多个实例。所以,我们之前是分有两层概念的,第一层是服务,而第二层是实例,一个服务可以包含多个实例。
不过啊,随着我们的业务规模越来越大,那么我们就会考虑更多的问题了。比如说,我们现在我们把所以的实例都部署在一个机房,就像你把鸡蛋放在一个篮子里,要是哪一天,不小心篮子翻了,蛋不就全打了吗?那你的机房要是天灾人祸出了问题,那整个服务不久完了吗?
所以,为了解决这个问题,我们会将一个服务的多个实例部署到多个机房。特别像阿里和京东这种财大气粗的,我全国各地都整些机房。一个倒了,还有其他的在正常运行。这就叫容灾。
而我们的Nacos服务分级存储模型,就是引入了类似机房的概念或者地域的概念。他把同在一个机房的多个实例称为一个集群。比方说杭州的某一个服务的机房的所有实例就称杭州的集群,北京机房的服务实例就称为北京的集群。
所以在nacos的服务分级存储模型中,一级是服务,往下是集群,再往下是实例。
那为什么Nacos要引入这样的服务分级的模型呢?我原来直接用服务找实例不好吗?
我们设想有这样一种情况,比方说我有一个杭州的机房,里面有order-service的集群和user-service的集群,然后我还有一个上海的机房,也是一样的配置,将来还可能会有北京机房等等。现在我们的order-service想要访问user-service,他有两种选择,一种是在自己本地访问,一种是去局域网外访问,你觉得它该选哪一个啊?肯定选本地啊!我们局域网内的访问距离比较短,速度就比较快,延迟也就比较低。而你跨越了集群的访问,比如说你从杭州去请求广州,达到了数百公里,这个时候延迟是非常高的。所以,在服务调用时应该尽可能地去访问本地集群,只有在本地集群不可用的情况下,才去访问其他的集群。
我们现在还没有配置集群,我们进入nacos的控制台,点开一个服务的详情:
会发现它的集群为DEFAULT ,也就是说没有配置集群。
下面就来学习一下如何配置一个服务的集群。
6.配置服务集群属性
我们有3个userservice服务,假如我们想要前两个user服务的集群放到上海集群,最后一个user服务放到杭州集群。来模拟一下这种跨集群部署的方式。
修改user-service的application.yml文件,添加集群配置:
spring: cloud: nacos: server-addr: localhost:8848 discovery: cluster-name: HZ # 集群名称
编写好配置文件后,我们先启动前面的两个服务实例:
然后我们要配置第三个实例的集群,我们再修改yml配置文件:
spring: cloud: nacos: server-addr: localhost:8848 discovery: cluster-name: SH # 集群名称
然后再启动最后一个服务(前两个服务不要关掉):
或者在服务配置里面配置集群:
我们再次打开Nacos的控制台,然后点击用户服务的详情:
还没有完,我们最终想要实现的是order-service远程调用user-service时,优先选择本地集群。因此,我们还需要给order-service也配置一个集群属性。
下面回到idea,为order-service也设置一下集群属性。我们配置为杭州HZ,然后重启order-service。
7.NacosRule负载均衡
我们清空日志后,在浏览器访问order服务获取三个订单数据,然后回到idea的控制台看日志。会发现8081,8082,8083端口的三个服务都被访问了。
我们发现,order-service发起远程调用的时候居然没有选择同集群的8081和8082。它仍然采用的是轮询方案,这又是什么原因啊?
我们知道,服务在选择一个实例时,全都是由负载均衡的规则来决定的。我们现在没有配置,默认的就是轮询的规则。所以要想实现优先同集群访问的负载均衡规则,我们必须去修改负载均衡。
默认的ZoneAvoidanceRule并不能实现根据同集群优先来实现负载均衡。因此Nacos中提供了一个NacosRule的实现,可以优先从同集群中挑选实例。
(1) 给order-service配置集群信息(上一节配好了,就可以不用配了)
userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
(2) 修改负载均衡规则
修改order-service的application.yml文件,修改负载均衡规则:
userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
然后,我们重新启动一下order-service服务,然后在浏览器里多访问几次订单查询。
我们发现只有8081和8082的控制台才有日志,而8083的控制台没有日志。这说明我们已经实现了Nacos同集群优先的负载均衡。
我们还会发现Nacos的一个特点就是它在8081和8082并不是轮询,是随机的。
也就是说,Nacos规则优先选择本地集群,在集群内,随机选择不同的服务实例进行负载均衡。
我们在来演示一下跨集群的访问吧,在idea里面把8081和8082的两个HZ集群的服务全部关闭,然后Nacos控制台会显示健康的实例数只有一个了。然后我们浏览器访问订单服务。
会发现8083的日志出现了,并且order-service服务也有调用远程集群的提示日志,这证明order-service进行了跨集群的访问。
8.服务实例的权重设置
实际部署中会出现这样的场景:
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求。
但默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题。因此,Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。
在nacos控制台,找到user-service的实例列表,点击编辑,即可修改权重:
在弹出的编辑窗口,修改权重:
我们把8081实例的权重值设置为 0.1 ,理论上讲8081被访问到的概率就会是8082的十分之一了。
注意:如果权重修改为0,则该实例永远不会被访问
把实例的权重调成0时,这个实例就压根不会被访问,那这有啥作用呢?
在我们以前,一个服务我们想要对他做一个版本的升级,我们是不是要把它重启啊,但是你光天化日之下你去重启一个服务,你好意思吗?用户都还在访问呢,你一重启客户都访问不上了,这样做就有问题啊。所以说我们不能随便去重启的。
我们有了权重之后,我们是不是可以这么做呢?假设我们有多个服务器8081、8082、8083(这里假设一下),我先把8081的服务的权重调成0,这个时候8081就不接收用户请求了。此时我对这台服务器做停机,用户就不会有感知了。我们就可以对8081进行一些版本的升级,升级完成之后,我再重启,并且权重我也先不调太大,先放少数用户进来测试看看行不行,如果没有问题,我们就可以依次扩大比例,依次都升级。用户是无感知的,这可以做到平滑升级,非常优雅。
9.环境隔离
Nacos提供了namespace来实现环境隔离功能。
我们知道Nacos是一个注册中心,它还是一个数据中心。所以在Nacos里面,它为了去做数据和服务的管理,会有一个环境隔离的概念。
Nacos中服务存储和数据存储的最外层都是一个namespace的东西,用来做最外层隔离。
nacos中可以有多个namespace
namespace下可以有group、service等
不同namespace之间相互隔离,例如不同namespace的服务互相不可见
有人可能会问,我们既然把服务实例划分成了集群,怎么要再整一个隔离呢?服务划分和实例划分是基于业务去做的划分,但事实上我们会有开发环境、测试环境、生产环境的变化吧。所以我们会基于这种环境变化去做隔离,namespace就是来做这样一件事情的。
而至于Group是分组的意思,把一些业务相关度比较高的服务放到一个组。假设你的订单服务和支付服务业务相关度比较高,那你就可以把它们放到一个Group里面去。
所以这是概念上的一个划分,他不是要求你必须得用这个来划分,你可以选择来用namespace或group,这不是强制的。
下面就来演示一下Nacos的使用。
10.创建namespace环境隔离
默认情况下,所有service、data、group都在同一个namespace,名为public:
我们点击命名空间栏后,右上角可以点击新建命名空间:
我们可以点击页面新增按钮,添加一个namespace:
然后,填写表单:
然后点击确定。然后切换到服务列表:
11.给微服务配置namespace
给微服务配置namespace只能通过修改配置来实现。
例如,修改order-service的application.yml文件:
spring: cloud: nacos: server-addr: localhost:8848 discovery: cluster-name: HZ namespace: b4401444-96e0-4b9a-a58b-9b24b74bfdfd # 命名空间,填ID