生产环境布置nacos及dubbo
Nacos,阿里巴巴提供的构建云本地应用的动态服务发现、配置中心和服务管理平台
可以查看Nacos官方文档
特性
服务发现和管理
动态服务发现是以服务为中心体系结构的关键。
动态配置服务
动态配置服务,外部化和动态的管理所有环境中的配置
动态DNS
支持加权路由,动态DNS服务在数据中心内的生产环境中间层负载均衡,灵活路由,流量控制、解析DNS服务,实现基于DNS的服务发现,最大程度降低耦合到特定于公司项目服务发现APi的风险
生产等级
阿里巴巴开源
支持数百万种服务的大规模方案
具有企业级SLA(服务级别协议)的开源产品
Nacos架构图
核心概念
==服务==
特定信息的检索或一组操作的执行,其目的是不同的客户端可以为不同的目的重用,支持主流服务生态,K8s、RPC、spring cloud RESTful
==服务注册中心==
服务实例及元数据的数据库,服务实例在启动时注册到服务注册表,在关闭的时候注销,服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查API来验证它是否能够处理请求、
*服务元数据 (Service Metadata)*
服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据
** 服务提供方 (Service Provider)**
是指提供可复用和可调用服务的应用方
服务消费方 (Service Consumer)
是指会发起对某个服务调用的应用方
配置及配置管理省略…
名字服务 (Naming Service)
提供分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的2大场景。
** 配置服务 (Configuration Service)
在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。
使用及部署
基于Docker安装Nacos
拉取镜像
1 docker pull nacos/nacos-server
创建目录及配置文件
创建两个目录,分别是初始化目录和日志目录
1 mkdir -p/opt/nacos/init.d/opt/nacos/logs
新建配置文件
1 vim /opt/nacos/init.d/custom.properties
在文件中添加内容
1 management.endpoints.web.exposure.include=*
创建并启动容器(默认端口8848)
1 省略: Mode= stangdalone(单机版)
挂载配置文件和日志文件
使用MySQL数据库,配置—e变量
配置
1 2 单机为例: docker run -d -p 8848 :8848 -p 9848 :9848 -e MODE=standalone -e PREFER_HOST_MODE=hostname -v /opt/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties -v /opt/nacos/logs:/home/nacos/logs --restart always --name nacos nacos/nacos-server
注意: Nacos服务器的版本如果是2.0.x。需要额外绑定端口 9849。否则无法实现服务的注册与发现。因为nacos服务器版本是2.0.x时,要求服务注册时,检查gRPC端口,此端口为9848,且端口无法访问时,服务启动抛出异常,因为nacos-discovery连接nacos-server的时候,gRPC端口无法访问,认为当前服务注册失败。
启动Nacos,访问可视化页面
访问:http://ip:8848/nacos
默认账号密码为nacos
使用Nacos做注册中心注意
Nacos支持HTTP和RPC协议访问。在导入Nacos依赖后内置Ribbon。和Eureka相同,都支持同名应用程序的负载均衡。
所以在使用Nacos作为注册中心的时候除了和Eureka依赖及配置文件不一样,其他流程都是一样的。
注意:Spring Cloud Alibaba依赖的Spring Boot最高版本只能是2.3.x。更高版本的spring boot和 spring cloud alibaba有兼容错误。启动失败。
注意:spring cloud alibaba 2021版本依赖,在使用openfeign技术做远程服务调用的时候,需要spring boot2.4.2及更高版本中的loadbalancer支持。但是启动的时候,必须使用spring boot 2.3.x版本中的spring-boot-context才能启动。有依赖冲突。无法实现服务的正常发现。暂时使用spring cloud alibaba2.2.x版本可以正常基于openfeign实现远程服务调用。
导入项目pom依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3 .12 .RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR12</version> <type>pom</type> <scope>import </scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2 .7 .RELEASE</version> <type>pom</type> <scope>import </scope> </dependency> </dependencies> </dependencyManagement>
父项目下新建Provider,配置依赖
1 2 3 4 5 6 7 8 9 10 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
编写配置文件
新建APPlocation.yml
server-addr:配置nacos的ip和端口。
1 2 3 4 5 6 7 8 9 server: port: 8080 spring: application: name: provider cloud: nacos: discovery: server-addr: ip:8848
新建控制器
新建com.dffy.controller.ProviderController
该控制器是为了让另一个项目调用的。
1 2 3 4 5 6 7 @RestController public class ProviderController { @RequestMapping("/provider") public String provider () { return "provider-controller" ; } }
新建启动类
新建com.dffy.ProviderApplication
1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class ProviderApplication { public static void main (String[] args) { SpringApplication.run(ProviderApplication.class,args); } }
启动项目
启动项目中可以在Nacos控制台中发现注册的信息
新建Consumer项目
在父项目下新建及配置依赖
1 2 3 4 5 6 7 8 9 10 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
新建配置文件
在resources下新建application.yml
端口和应用程序名不可重复
1 2 3 4 5 6 7 8 9 server: port: 8081 spring: application: name: consumer cloud: nacos: discovery: server-addr: ip:8848
新建配置类
新建com.dffy.config.ConsumerConfig
1 2 3 4 5 6 7 8 @Configuration public class ConsumerConfig { @Bean @LoadBalanced public RestTemplate restTemplate () { return new RestTemplate (); } }
新建service及实现类
http://provider/provider 中第一个provider是另一个项目的应用程序名。第二个provider是控制器名称。
1 2 3 public interface ConsumerService { String consumer () ; }
1 2 3 4 5 6 7 8 9 10 11 @Service public class ConsumerServiceImpl implements ConsumerService { @Autowired private RestTemplate restTemplate; @Override public String consumer () { String result = restTemplate.getForObject("http://provider/provider" , String.class); return result; } }
新建控制器
1 2 3 4 5 6 7 8 9 10 @RestController public class ConsumerController { @Autowired private ConsumerService consumerService; @RequestMapping("/consumer") public String consumer () { return consumerService.consumer(); } }
新建启动类ConsumerApplication
1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class ConsumerApplication { public static void main (String[] args) { SpringApplication.run(ConsumerApplication.class,args); } }
运行项目,是否成功注册
测试服务调用
浏览器输入ip:8081/consumer
使用Nacos作为Dubbo的注册中心
新建父项目
配置pom依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3 .5 .RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR9</version> <type>pom</type> <scope>import </scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2 .3 .RELEASE</version> <type>pom</type> <scope>import </scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3 .5 .RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2 .3 .RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> <version>2.2 .3 .RELEASE</version> </dependency> </dependencies> </dependencyManagement>
新建API子项目
新建项目api.
此项目作为Dubbo发布接口的项目
新建接口
新建.api.DemoApiService(不能和Consumer的service接口名重复)
1 2 3 public interface DemoApiService { String demo () ; }
新建Provider子项目
配置pom依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <dependencies> <dependency> <artifactId>api</artifactId> <groupId>com.bjsxt</groupId> <version>1.0 -SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> </dependencies>
新建配置文件
新建application.yml
dubbo.scan.backages:扫描@DubboService所在包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 dubbo: # scan: # base-packages: com.flysoft.service.impl # cloud: # subscribed-services: dubbo-provider # 订阅的服务,默认 * protocol: # dubbo 协议 name: dubbo # dubbo 协议端口( -1 表示自增端口,从 20880 开始) port: -1 registry: # 挂载到注册中心 address: nacos: spring: application: # Dubbo 应用名称 name: dubbo-provider # main: # Spring Boot 2.1 需要设定 # allow-bean-definition-overriding: true cloud: nacos: # Nacos 服务发现与注册配置 discovery: server-addr: ip:8848
新建实现类
service.impl.DemoServiceImpl
1 2 3 4 5 6 7 @DubboService public class DemoServiceImpl implements DemoApiService { @Override public String demo () { return "dubbo-provider-service" ; } }
新建启动类
.ProviderApplication
1 2 3 4 5 6 7 8 @SpringBootApplication @EnableDiscoveryClient @EnableDubbo public class ProviderApplication { public static void main (String[] args) { SpringApplication.run(ProviderApplication.class,args); } }
新建Consumer项目
配置pom依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <dependencies> <dependency> <artifactId>api</artifactId> <groupId>com.bjsxt</groupId> <version>1.0 -SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> </dependencies>
新建配置文件application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 dubbo: registry: # 挂载到 Spring Cloud 注册中心 address: nacos: # cloud: # subscribed-services: dubbo-provider protocol: # dubbo 协议 name: dubbo # dubbo 协议端口( -1 表示自增端口,从 20880 开始) port: -1 server: port: 8081 spring: application: # Dubbo 应用名称 name: dubbo-consumer # main: # Spring Boot 2.1 需要设定 # allow-bean-definition-overriding: true cloud: nacos: # Nacos 服务发现与注册配置 discovery: server-addr: ip:8848
新建service及实现类
service.ConsumerService
1 2 3 public interface ConsumerService { String consumer () ; }
1 2 3 4 5 6 7 8 9 @Service public class ConsumerServiceImpl implements ConsumerService { @DubboReference private DemoApiService demoApiService; @Override public String consumer () { return demoApiService.demo(); } }
新建控制器
.controller.ConsumerController
1 2 3 4 5 6 7 8 9 10 @RestController public class ConsumerController { @Autowired private ConsumerService consumerService; @RequestMapping("/consumer") public String consumer () { return consumerService.consumer(); } }
新建启动类
.ConsumerApplication
1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class ConsumerApplication { public static void main (String[] args) { SpringApplication.run(ConsumerApplication.class,args); } }
基于OpenFeign实现远程服务调用
修改pom
增加依赖
1 2 3 4 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
定义OpenFeign调用接口
1 2 3 4 5 @FeignClient("dubbo-provider") public interface CallProviderInterface { @RequestMapping("/provider") String test () ; }
修改控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @RestController public class ConsumerController { @Autowired private ConsumerService consumerService; @Autowired private CallProviderInterface callProviderInterface; @RequestMapping("/consumer2") public String consumer () { return callProviderInterface.test(); } @RequestMapping("/consumer") public String consumer () { return consumerService.consumer(); } }
修改启动类
1 2 3 4 5 6 7 8 @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ConsumerApplication { public static void main (String[] args) { SpringApplication.run(ConsumerApplication.class,args); } }
测试
实现Nacos作为配置中心
在Nacos中新建配置文件
访问可视化
配置列表点击+
添加配置文件信息
Data ID:名称任意。此名称作为配置文件名称(又可以叫前缀(prefix))
Group: 在没有自己建立组时默认为DEFAUL_GROUP。此值不需要修改
配置格式:选择properties或yml。此配置影响到客户端加载配置文件时配置。
配置内容:根据所选配置格式,按照指定格式填写内容。
点击发布按钮后弹出配置文件信息
点击确定按钮不会自动关闭这个页面。而是回到编辑视图
在配置列表中查看
新建项目
任意名称的项目
编写pom
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3 .5 .RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3 .5 .RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2 .3 .RELEASE</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- <dependency>--> <!-- <groupId>org.springframework.cloud</groupId>--> <!-- <artifactId>spring-cloud-dependencies</artifactId>--> <!-- <version>Hoxton.SR8</version>--> <!-- <type>pom</type>--> <!-- <scope>import </scope>--> <!-- </dependency>--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2 .3 .RELEASE</version> <type>pom</type> <scope>import </scope> </dependency> </dependencies> </dependencyManagement>
编写配置文件
新建配置文件
新建bootstarap.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 server: port: 8070 spring: cloud: nacos: discovery: server-addr: ip:8848 config: # 指定配置中心的地址和配置中心使用的数据格式 server-addr: ip:8848 # 默认加载文件扩展名为properties file-extension: properties # group默认值为DEFAULT_GROUP # group: DEFAULT_GROUP # 加载的配置文件名称默认值为应用程序名 # prefix: ${spring.application.name} application: name: config-client
新建service及实现类
.service.ConfigClientService及实现类
Nacos支持动态刷新功能。在获取分布式配置中心内容的类上添加@RefreshScope可以热刷新
1 2 3 public interface ConfigClientService { String configClient () ; }
1 2 3 4 5 6 7 8 9 10 11 12 @Service @RefreshScope public class ConfigClientServiceImpl implements ConfigClientService { @Value("${my.name}") private String name; @Value("${my.age}") private Integer age; @Override public String configClient () { return name+"---" +age; } }
新建控制器
.controller.ConfigServerController
1 2 3 4 5 6 7 8 9 10 @RestController public class ConfigServerController { @Autowired private ConfigClientService configClientService; @RequestMapping("/") public String configServer () { return configClientService.configClient(); } }
新建启动类
.ConfigClientApplication
1 2 3 4 5 6 @SpringBootApplication public class ConfigClientApplication { public static void main (String[] args) { SpringApplication.run(ConfigClientApplication.class,args); } }
测试