Nacos配置文件和注册中心,还有各种踩坑,你遇到的问题这里都会有
新公司这边配置中心和服务发现采用的是Spring Cloud Alibaba的Nacous,以前我这边写微服务用的是SpringCloud的Eureka注册中心,在我的博客springcloud五大组件永远滴神——成神之路中也详细分析了Eureka服务注册和发现中心的用法,大家可以想去了解Eureka的
新公司这边配置中心和服务发现采用的是Spring Cloud Alibaba的Nacous,以前我这边写微服务用的是SpringCloud的Eureka注册中心,在我的博客springcloud五大组件永远滴神——成神之路中也详细分析了Eureka服务注册和发现中心的用法,大家可以想去了解Eureka的也可以去看那篇文章详细了解,这篇呢我就吧最近背着大家偷偷学的阿里巴巴的Nacos知识点来给大家一起分享下,毕竟和大家分享知识,不仅仅能够帮助你们,同样也能够帮助我理解更多和记忆更深,分享就是帮助他人,成长自己的过程嘛,来吧,老规矩,废话少说,上干货。
1、Nacos是什么?
每学习一项新的知识点,首先就是要了解它是什么?它又能干什么?这是千古不变的。Nacos是Dynamic Naming and Configuration Service简称,Na是naming即是注册,co是configuration即配置,service是该注册和配置中心都是以服务为核心。服务在nacos中是一等公民。
Nacos注册中心为CS架构模式,server采用Java编写,为client提供注册服务与配置服务。client可以用多种语言实现,client与微服务嵌套在一起。使用Nacos肯定是先下载Nacos Server,然后启动运行;然后client服务往server端进行注册与发现。这里的话我就不讲Nacos Server如何下载与安装了,大家可以自行百度哦。
2、Nacos 简单功能的介绍与使用
安装好Nacos Server后,大家可以访问地址http://127.0.0.1:8848/nacos/#/login来登录Nacos,默认账号密码是nacos,nacos;大家输入账号密码后登录进去是如下页面:
上图中大家可以发现左侧的菜单栏中分为配置管理、服务管理和集群管理三大部分,下面我简单的给大家介绍下这三大部分的含义和简单用法。
2.1、配置管理
配置管理,即是对配置中心的管理;配置中心就是将配置文件从应用中剥离出来进行统一管理,不需要我们的服务自己去管理配置。其管理配置流程大致如下图所示:
Namespace命名空间、Group分组、集群这些都是为了进行归类管理,把服务和配置文件进行归类,
分类之后就可以实现一定的效果,比如隔离,对于服务来说,不同命名空间中的服务不能够互相访问调用
Namespace:命名空间,对不同的环境进行隔离,比如隔离开发环境、测试环境和生产环境
- Group:分组,将若干个服务或者若干个配置集归为一组,通常习惯一个系统归为一个组
- Service:某一个服务,比如简历微服务
- DataId:配置集或者可以认为是一个配置文件
Nacos抽象出了Namespace、Group、Service、DataId等概念,具体代表什么取决于怎么用(非常灵 活),推荐用法如下
概念 | 描述 |
---|---|
Namespace | 代表不同的环境,如开发dev、测试test、生产环境prod |
Group | 代表某项目,比如拉勾云项目 |
Service | 某个项目中具体xxx服务 |
DataId | 某个项目中具体的xxx配置文件 |
namespace+group+Data Id在页面如下所示:
新建配置如下所示:
好了以上就是配置管理的简单使用。
2022年04月01日来给大家继续踩个坑,nacos的yml配置文件名称必须要有.yaml;举例说明:项目名称为spring.applicatuon.name=test,这里你会以为在nacos中读取的配置文件名称为test,那么你就错了,实际读取的名称为test.yaml,一定要注意,否则读取失败。
图片展示如下所示:
2.2、服务管理
服务管理顾名思义就是管理各种微服务,其页面如下所示:
2.3、集群管理
集群管理就是对毫无关联的各个Nacos进行统一起来,构成一个集群来进行统一。
3、Nacos配置中心简单demo
这里我先简单的介绍下如何读取Nacos中的配置文件,这种事最原始的,在真正的企业开发过程中是不会使用的。
首先我们在Nacos Server中创建配置中心文件。
配置内容大家根据自己的实际情况进行编写。
然后编写代码如下所示:
package com.ygl.nacos;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import java.util.Properties;
import java.util.concurrent.Executor;
/**
* @author yangaoling
* @version 1.0
* @date 2021/4/30 14:50
*/
public class SimpleDemoMain {
public static void main(String[] args) throws NacosException, InterruptedException {
//使用nacos client 远程获取nacos服务上的配置信息
//nacos地址+端口号
String serverAddr = "127.0.0.1:8848";
//nameSpace
//注意namespace中的s是小写,千万不能写错,否则就不行
String namespace = "b6cb281f-df22-4f43-9048-ff16ebcdec65";
//group
String group = "DEFAULT_GROUP";
//data id
String dataId = "nacos-simple-demo.yaml";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
properties.put("namespace", namespace);
//获取配置
ConfigService configService = NacosFactory.createConfigService(properties);
//String dataId, String group, long timeoutMs
String config = configService.getConfig(dataId, group, 5000);
System.out.println("获取内容:" + config);
//添加配置监听
//String dataId, String group, Listener listener
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
//当配置有变化的时候获取通知
@Override
public void receiveConfigInfo(String s) {
System.out.println("变化啦:" + s);
}
});
//模拟监听(来个死循环)
while (true) {
//休眠两秒
Thread.sleep(2000);
}
}
}
我简单的讲解下代码思维逻辑:
1、创建Properties配置属性,往属性properties中添加地址serverAddr
,serverAddr包括nacos地址和端口号,例如:127.0.0.1:8848;再添加命名空间namespace,注意一定不要写错这两个哈,还有namespace是写后面一行号,如下图所示:
2、根据服务配置地址和命名空间来获取所有配置文件,ConfigService configService = NacosFactory.createConfigService(properties);
这行代码就是获取所有配置文件。
3、根据Data Id和group来获取具体的配置文件内容;String config = configService.getConfig(dataId, group, 5000);
这行代码的左后一个5000含义就是代表获取超时时间是5000ms。config的内容就是该配置文件的具体内容。
4、上述代码中还添加了个配置监听,它的作用就是当我们更改配置文件内容重新发布后,这里会进行实时监听。
代码运行结果如下图所示:
4、Nacos配置中心集成Spring Cloud
刚刚第三部分中,我们讲了java简单使用Nacos的Demo,通过上述代码我们明显可以发现如果在开发中那样使用Nacos的话真的太麻烦了,接下来我们来讲解Spring Cloud开发中如何使用Nacos。
4.1、创建maven项目nacos-config,然后引入部份依赖
pom依赖如下代码所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ygl.nacos</groupId>
<artifactId>nacos-config</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>service1</module>
<module>service2</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
上述依赖引入的是alibaba的cloud下的dependencies依赖;springframework的cloud下的dependencies依赖;sprngBoot的dependencies依赖。
4.2、创建service1模块
创建成功首先引入alibaba下的nacos-config依赖和springBoot下的starter-web依赖,pom.xml如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>nacos-config</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service1</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
这里引入了阿里巴巴的nacos-config依赖和starter-web依赖。
接下来编写yml配置文件,代码如下:
server:
port: 56010 #端口号
spring:
application:
name: service1 #spring名称
cloud:
nacos:
config:
# 关闭从nacos中读取配置
# enabled: false
server-addr: 127.0.0.1:8848 # 配置中心地址
file-extension: yaml # dataId的名称就是application的name加file-extension service1.yaml
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65 # 命名空间
group: TEST_GROUP # 组名
#共享data-id方式
#自定义共享data-id,它只认 DEFAULT_GROUP组的配置文件
# shared-dataids: ext-config-common01.properties,ext-config-common02.properties,ext-config-common03.properties
# refreshable-dataids: ext-config-common01.properties
#扩展data-id方式 扩展配置
#在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
ext-config[0]:
data-id: ext-config-common01.properties
#不在默认的组,不支持动态刷新
ext-config[1]:
data-id: ext-config-common02.properties
group: GLOBALE_GROUP
#不在默认的组,支持动态刷新
ext-config[2]:
data-id: ext-config-common03.properties
group: REFRESH_GROUP
refresh: true #动态刷新
yml中的各个含义我在后面注释中已经详细注明,这里我再详细说几点:
1、server-addr是配置中心地址;
2、file-extension文件类型,注意,这里要访问的Data Id名称是由application.name+file-extension;这里的data id名称是:service.yaml;
3、namespace是命名空间名称;
4、group是组名;
5、ext-confid[]中是扩展的data-id的方式,不再过多详述。
注意:最最最重要的是这里的nacos配置一定要写在bootstrap.yml中,如果你写在application.yml中将是无法生效读取的。
nacos中的service.yml配置文件如下面代码所示:
common:
name: service1 config new
school: qinghua
controller层测试是否能够读取到nacos中的service1.yml内容测试代码如下所示:
package com.ygl.nacos.service2.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author yangaoling
* @version 1.0
* @date 2021/4/30 17:16
*/
@RestController
public class TestController {
@Autowired
private ConfigurableApplicationContext applicationContext;
//这里采用Value注解直接将配置文件中的common.name的值注入进config1
@Value("${common.name}")
private String config1;
@GetMapping("/getConfigs")
public String getConfigs() {
System.out.println("======"+config1);
//获取nacos配置文件key为common.name的值
return applicationContext.getEnvironment().getProperty("common.name");
}
}
启动类和平常没任何区别,这里就不再过多描述,
启动项目后即可查看到读取的配置文件内容。
5、Nacos服务注册与发现
上面章节中给大家分享了Nacos配置中心,这是Nacos中一个重要功能,接下来本章节中给大家介绍Nacos的还有重要功能之一:服务发现与注册。
什么是注册中心、服务注册、服务发现?
我先给大家打个比方来方便大家了解这三者的关系,咱们就拿买房者、卖房者,房屋中介这三个来对比。卖房者将房子交给房屋来管理就类似服务注册,房屋中介管理房屋买卖类似注册中心,买房者从中介了解房子信息就类似服务发现。下图表示其关系:
我们可以将注册中心拆解成两部分,也就是注册、中心,注册的意思也见名知意,就是将某个东西注册到某个平台上,平台管理我们注册的东西,而中心就可以看成一个统一管理信息的平台,两个部分连起来就是注册中心,也就是统一管理所有注册信息的平台。
而服务注册指的是服务在启动时将自身的信息注册到注册中心中,方便信息进行统一管理。服务注册是客户端向注册中心提交信息的动作。
服务发现指的是从注册中心获取对应服务的信息。服务发现是客户端向注册中心获取信息的动作。
服务消费者需要知道服务提供者的信息,比如 IP、 端口等信息,才能发起远程调用,所以需要通过拉取的动作从注册中心拉取对应服务的信息,然后发起调用。
通过上面举例和画图,相信大家对服务注册、注册中心和服务发现有较深理解。
注册中心原理:
Nacos服务分级模型:
接下来在项目中完成配置管理和服务注册和发现功能。
首先来个比较简单的生产者消费者的项目,直接将生产者注入进注册中心,然后消费者也注册进注册中心,然后消费者利用Feign来获取所需要的服务数据,这种是类似http请求的模式。
5.1、搭建项目,创建父工程nacos-discovery
然后引入依赖,pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ygl.nacos</groupId>
<artifactId>nacos-discovery</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>quickstart-provider</module>
<module>quickstart-consumer</module>
<module>nacos-micro-service</module>
</modules>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
5.2、创建生产者模块quickstart-provider
首先引入nacos的discovery依赖,starter-web依赖和feign组件,pom.cml依赖如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>nacos-discovery</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>quickstart-provider</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
然后创建application.yml配置文件,设置要将服务注册到注册中心的地址和命名空间,application.yml配置文件如下所示:
server:
port: 56010
spring:
application:
name: quickstart-provider
cloud:
nacos:
discovery:
# 注册中心地址
server-addr: 127.0.0.1:8848
# 注册中心命名空间
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
# 日志有关配置
logging:
level:
root: info
org.springframework: info
创建controller层,写测试接口,代码如下:
@RestController
public class ProviderController {
//添加打印日志
private static final Logger LOG = LoggerFactory.getLogger(ProviderController.class);
/**
* 测试
*
* @Author: ygl
* @Date: 2021/5/13
*/
@GetMapping("/service")
public String service() {
LOG.info("provider invoke");
return "provider invoke";
}
}
这里和平常写的没有任何区别
最后写代码启动类,这里和平常启动类要有区别与不同了,要将该服务注册进注册中心,要添加开启服务发现注解@EnableDiscoveryClient
和启用feign注解@EnableFeignClient;启动类代码如下所示:
package com.ygl.nacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author yangaoling
* @version 1.0
* @date 2021/5/13 17:45
*/
@SpringBootApplication
//开启服务发现客户端 和@EnableEurekaClient注解一样功能 都是能够让注册中心能够发现,扫描到该服务。
@EnableDiscoveryClient
//启用feign客户端
@EnableFeignClients
public class NacosProviderApp {
public static void main(String[] args) {
SpringApplication.run(NacosProviderApp.class, args);
}
}
这里我们就完成了生产者的模块的编写,启动该模块后,我们就能够将该项目注册进注册中心,在注册中心中能够看看到该项目,如图所示:
点击详情后,可以看到该服务的详情,包括IP、端口、权重和健康状态等等。
点击编辑,可以编辑部分内容,注意下权重,权重越大,在轮询调用的过程中被选中的概率越高。
5.3、创建消费者模块quickstart-consumer
老规矩,先引入我们所需要的依赖:nacos的discovery依赖、starter-web依赖和openfeign依赖。代码如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>nacos-discovery</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>quickstart-consumer</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
创建application.yml文件,设置注册中心地址和命名空间,代码如下所示:
server:
port: 56020
spring:
application:
name: quickstart-consumer
cloud:
nacos:
discovery:
server-addr: 49.235.125.139:8848
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
创建提供者客户端接口,利用feign组件从注册中心中获取其服务接口,代码如下所示:
//注解中的值是提供者中application.yml文件中spring.application.name的值
@FeignClient("quickstart-provider")
public interface ProviderClient {
//注意这个接口必须与生产者接口保持一致,任何地方都不可以不一样,否则将失败
@GetMapping("/service")
public String service();
}
创建controller层,直接调用服务生产者接口。代码如下所示:
@RestController
public class ConsumerController {
private static final Logger LOG = LoggerFactory.getLogger(ConsumerController.class);
//动态代理对象,内部远程调用服务生产者
@Autowired
ProviderClient providerClient;
@GetMapping("/service")
private String service() {
LOG.info("consumer invoke");
String service = providerClient.service();
return "consumer invoke :" + service;
}
}
利用@Autowired
注解将服务生产者从注册中心拉取,直接调用即可,运行即可。
启动类上仍然是添加开启服务发现注解和开启feign注解,代码如下:
@SpringBootApplication
//开启服务发现客户端 和@EnableEurekaClient注解一样功能 都是能够让注册中心能够发现,扫描到该服务。
@EnableDiscoveryClient
//启用feign客户端
@EnableFeignClients
public class NacosConsumerApp {
public static void main(String[] args) {
SpringApplication.run(NacosConsumerApp.class, args);
}
}
启动运行后,该服务将会注册进nacos注册中心中,而且调用接口,将会调取生产者服务暴露的service接口。这是简单利用http来远程调用服务的方式。
5.4、Spring Cloud Alibaba 综合集成架构演示
前面讲到,Spring Cloud是一个较为全面的微服务框架集,集成了如服务注册发现、配置中心、消息总线、负载均衡、断路器、API网关等功能实现。而在网上经常发现Spring Cloud与阿里的Dubbo进行选择对比,这样比较其实是很不恰当,前者是一套较为完善的架构方案,而Dubbo只是服务治理与RPC实现方案。
在此之前,我们已经学到如何使用Spring Cloud Alibaba来集成Nacos与Spring Cloud的应用,并且在此之下可以和传统的Spring Cloud应用一样的使用Ribbon或Feign来微服务之间的协作,由于Feign是基于Http Restful的调用,在高并发的性能下不够理想,RPC方案能否切换为Dubbo?Spring Cloud与阿里系若干组件能否完美集成?接下来就带领大家集成一个微服务基础架构。
5.4.1、总体架构
系统架构图:
组件说明:
API网关: 系统统一入口,屏蔽架构内部结构,统一安全拦截,采用Zuul实现。
application1: 应用1,模拟应用,提供http接口服务。
service-1: 微服务1,模拟微服务,提供dubbo接口服务。
service-2: 微服务2,模拟微服务,提供dubbo接口服务。
调用流程:
所有访问系统的请求都要经过网关,网关转发Http请求至application-1,application-1使用dubbo调用service1完成自身业务,而后service1调用service2完成自身业务。至此,完成所有组件贯穿。
架构中application与sevice的区别是什么?
- service提供了基础服务功能;application组装基础服务功能,提供给用户直接可用的业务。
- service服务粒度小、功能基础,不易发生改变;application提供上游业务功能,紧贴业务需求,容易发生改变。
- 形成service支撑application的整体架构,增加多变的application甚至不需要变动service。
5.4.2、工程结构说明
采用maven工程,结构如下:
nacos‐micro‐service 整体父工程
├─api‐gateway API网关,端口:56010
├─application‐1 应用1,端口:56020
├─service‐1 服务1父工程
│ ├─service‐1‐api 服务1API
│ |─service‐1‐server 服务1实现,端口:56030
|─service‐2 服务2父工程
| ├─service‐2‐api 服务2API
| |─service‐2‐server 服务2实现,端口:56040
5.4.3、创建父工程
创建 artifactId 名为 nacos-micro-service 的 Maven 工程,此父工程继承nacos-discovery父工程,间接指定了Spring boot、spring cloud 以及spring-cloud-alibaba的依赖版本。
5.4.4、实现application1
application1属于应用层,提供http接口服务。
(1)初始化 application-1 Maven 工程,pom.xml代码如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>nacos-micro-service</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>application-1</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.ygl.nacos</groupId>
<artifactId>service-1-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.4</version>
</plugin>
</plugins>
</build>
</project>
(2)实现application-1功能
@RestController
public class ApplicationController {
//注入service(基于dubbo协议)
@GetMapping("/service")
public String service() {
return "test";
}
}
(3)application1 配置
定义bootstrap.yml,代码如下所示:
server:
port: 56020
servlet:
context-path: /application1 # 根路径
spring:
application:
name: application1
main:
allow-bean-definition-overriding: true # 防止bean重复
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
cluster-name: DEFAULT
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
group: NACOS_MICROSERVICE_GROUP
(4) application1 启动
启动代码如下:
package com.ygl.microservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 15:32
**/
@SpringBootApplication
@EnableDiscoveryClient
public class Application1Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Application1Bootstrap.class, args);
}
}
当 Service1Bootstrap 启动后,应用 application1 将出现在 Nacos 控制台界面。
5.4.5、实现Service1
1、定义service1父工程,pom.xml代码如下:
<parent>
<artifactId>nacos-micro-service</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
2、定义service-1-api
为了方便其它服务调用dubbo服务,专门定义api工程,此工程将作为jar被其它工程依赖。
定义service-1-api工程,pom.xml如下:
<parent>
<artifactId>service-1</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-1-api</artifactId>
定义服务接口:
public interface ConsumerService {
public String service();
}
5.4.6、实现service-1-server
1、初始化service-1-server Maven工程
添加Maven相关依赖,代码如下:
<dependencies>
<dependency>
<groupId>com.ygl.nacos</groupId>
<artifactId>service-2-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ygl.nacos</groupId>
<artifactId>service-1-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</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>
2、实现Dubbo服务
//注意这个注解是Dubbo的Service注解,不是springframework的Service注解
@Service
public class ConsumerServiceImpl implements ConsumerService {
/**
* 实现service接口(dubbo接口实现内容)
* TODO
*
* @param
* @return String
* @author ygl
* @date 2021/5/14 15:46
**/
@Override
public String service() {
return "Consumer invoke ";
}
}
注意:Service注解是Dubbo的注解,千万不要给导错成springframework包下的注解了。
3、配置Dubbo服务
Service2 作为Dubbo服务消费方配置与服务提供方类似,注意,service1不仅是消费方,同时还是服务提供方:
service1的yml配置文件如下所示:
server:
port: ${port:56030}
spring:
application:
name: service1
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
cluster-name: DEFAULT
server-addr: 127.0.0.1:8848
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
config:
server-addr: 49.235.125.139:8848
file-extension: yaml
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
dubbo:
scan:
# dubbo 服务扫描基准包
base-packages: com.ygl.microservice
protocol:
# dubbo 协议
name: dubbo
# dubbo 协议端口
port: ${dubbo_port:20881}
registry:
address: nacos://127.0.0.1:8848
application:
# dubbo 运维服务是否开启
qos-enable: false
consumer:
# 启动时是否检查依赖的服务
check: false
以上yaml文件中,dubbo开头的为dubbo服务的配置:
dubbo.scan.base-packages
:指定Dubbo服务实现类的扫描基准包,将Dubbo包下的@Service注解标注的service暴露为Dubbo服务。dubbo.protocol
:Dubbo服务暴露的协议配置,其中子属性name
为协议名称,port
为dubbo协议端口号。dubbo.registry
:Dubbo服务注册中心配置,其中子属性address
的值为nacos://127.0.0.1:8848
,说明dubbo服务注册到nacos中。
yaml文件的上半部分配置为SpringCloud的相关配置:
spring.application.name
:Spring应用名称,用于Spring Cloud服务注册和发现;该值在Dubbo Spring Cloud加持下被视作dubbo.application.name
,因此无需再配置dubbo.application.name
。spring.cloud.nacos.config
:Nacos 配置中心配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口。spring.cloud.nacos.discovery
:Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 。
4、启动服务消费方应用
package com.ygl.microservice.service1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 15:59
**/
@SpringBootApplication
@EnableDiscoveryClient
public class Service1Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Service1Bootstrap.class,args);
}
}
当Service1Bootstrap
启动后,应用service1
将出现在nacos控制台的服务列表中。
启动成功,观察服务列表,如下图所示:
5.4.7、实现application1远程调用service1
现在service1已经暴露dubbo服务,并且注册到nacos中,下面实现application1调用service1
1、引用service1
在application1中引用service1
首先在pom.xml中引用service1-api的依赖
<dependency>
<groupId>com.ygl.nacos</groupId>
<artifactId>service-1-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
引用spring-cloud-starter-dubbo依赖,它会根据接口生成代理对象,代码如下:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
2、实现远程调用
package com.ygl.microservice.application1.controller;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ygl.microservice.service1.api.ConsumerService;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 15:09
**/
@RestController
public class ApplicationController {
//注入service(基于dubbo协议)
@Reference
ConsumerService consumerService;
@GetMapping("/service")
public String service() {
String service = consumerService.service();
return "test"+";远程调用service1:"+service;
}
}
注意: 这里的注解@Reference
是org.apache.dubbo.config.annotation
包下的
测试:
请求:http://127.0.0.1:56020/application1/service
consumerService生成代理对象,service1被调用。
5.4.8、实现service2
如上面设计所示,Service2需要暴露dubbo接口以供service1消费,若想在Spring cloud Alibaba中集成并使用dubbo。
1、定义父工程
定义service2父工程,pom.xml代码如下:
<parent>
<artifactId>nacos-micro-service</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
2、定义service-2-api
定义service-2-api工程,pom.xml如下:
<parent>
<artifactId>service-2</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
并定义服务接口,Dubbo 服务接口是服务提供方与消费方的远程通讯契约,通常由普通的 Java 接口(interface)来声明,如 ProviderService 接口:
package com.ygl.microservice.service2.api;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 17:11
**/
public interface ProviderService {
String service();
}
3、实现service-2-server
3.1、初始化service-2-server
的Maven工程
首先,创建artifactId
名为service-2-server
的Maven工程,并在pom.xml
中引入Dubbo Spring Cloud必要依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>service-2</artifactId>
<groupId>com.ygl.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-2-server</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.ygl.nacos</groupId>
<artifactId>service-2-api</artifactId>
<version>1.0-SNAPSHOT</version>
</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-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
</dependencies>
</project>
以上依赖说明:
service-2-api
:提供service-2-api
中ProviderServic
接口spring-cloud-starter-dubbo
:提供dubbo依赖spring-cloud-starter-alibaba-nacos-discovery
:提供nacos的服务注册和发现功能
3.2、实现dubbo服务
ProvicerService
作为暴露的Dubbo服务接口,服务提供方需要service-2-server
需要将其实现:
package com.ygl.microservice.service2.service.impl;
import org.apache.dubbo.config.annotation.Service;
import com.ygl.microservice.service2.api.ProviderService;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 17:15
**/
@Service
public class ProvicerServiceImpl implements ProviderService {
@Override
public String service() {
return "Provider invoke";
}
}
其中@Service
注解是Dubbo服务注解,仅声名该java服务实现为Dubbo服务,因此下一步需要将其配置Dubbo服务。
3.3、配置Dubbo服务
在暴露 Dubbo 服务方面,推荐开发人员外部化配置的方式,即指定 Java 服务实现类的扫描基准包。
Dubbo Spring Cloud 继承了 Dubbo Spring Boot 的外部化配置特性,也可以通过标注
@DubboComponentScan
来实现基准包扫描
同时,Dubbo 远程服务需要暴露网络端口,并设定通讯协议,完整的 YAML 配置如下所示:
server:
port: ${port:56040}
spring:
application:
name: service2
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
cluster-name: DEFAULT
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
dubbo:
scan:
base-packages: com.ygl.microservice
protocol:
port: ${dubbo_port:20891}
name: dubbo
registry:
address: nacos://127.0.0.1:8848
application:
# dubbo 运维服务是否开启
qos-enable: false
consumer:
# 启动时是否检查依赖的服务
check: false
启动服务提供方应用
Dubbo Spring Cloud 引导类与普通 Spring Cloud 应用并无差别,如下所示:
package com.ygl.microservice.service2.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 17:23
**/
@SpringBootApplication
@EnableDiscoveryClient
public class Service2Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Service2Bootstrap.class,args);
}
}
在Service2Bootstrap
启动之前,记得开启Nacos服务器,当Service2Bootstrap
启动之后,应用service2
将出现在Nacos控制台界面。
5.4.9、实现service1调用service2
引用service2
在service-1-server
中添加service-2-api
依赖
<dependency>
<groupId>com.ygl.nacos</groupId>
<artifactId>service-2-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
实现远程调用
代码如下所示:
package com.ygl.microservice.service1.service;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import com.ygl.microservice.service1.api.ConsumerService;
import com.ygl.microservice.service2.api.ProviderService;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 15:45
**/
//注意这个注解是Dubbo的Service注解,不是springframework的Service注解
@Service
public class ConsumerServiceImpl implements ConsumerService {
@Reference
ProviderService providerService;
/**
* 实现service接口(dubbo接口实现内容)
* TODO
*
* @param
* @return String
* @author ygl
* @date 2021/5/14 15:46
**/
@Override
public String service() {
String service = providerService.service();
return "Consumer invoke "+";service1远程调用service2:"+service;
}
}
测试:
请求地址:127.0.0.1:56020/application1/service
application1项目调用service1项目;service1项目调用service2项目
5.4.10、实现api-gateway
1、网关介绍
什么是网关?
原来的单体架构,所有的服务都是本地的,UI可以直接调用,现在按功能拆分成独立的服务,跑在独立的一般都在独立的虚拟机上的 Java进程了。客户端UI如何访问?他的后台有N个服务,前台就需要记住管理N个服务,一个服务下线/更新/升级,前台就要重新部署,这明显不服务我们拆分的理念,特别当前台是移动应用的时候,通常业务变化的节奏更快。另外,N个小服务的调用也是一个不小的网络开销。
有了网关作为服务统一入口,就可以避免上述问题,不仅如此,服务网关是在微服务前边设置一道屏障,请求先到服务网关,网关会对请求进行过虑、校验、路由等处理。有了服务网关可以提高微服务的安全性,网关校验请求的合法性,请求不合法将被拦截,拒绝访问。
- 提供统一服务入口,让微服务对前台透明
- 聚合后台的服务,节省流量,提升性能
- 提供安全,过滤,流控等API管理功能
什么是Zuul?
Spring Cloud Zuul是整合Netflflix公司的Zuul开源项目实现的微服务网关,它实现了请求路由、负载均衡、校验过虑等 功能。
Zuul与Nginx怎么配合使用?
Zuul与Nginx在实际项目中需要配合使用,如下图,Nginx的作用是反向代理、负载均衡,Zuul的作用是保障微服务的安全访问,拦截微服务请求,校验合法性及负载均衡。
搭建网关工程
初始化api-gateway
Maven工程,代码如下:
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
api-gateway配置
server:
port: 56010
spring:
application:
name: api-gateway
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
cluster-name: DEFAULT
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: b6cb281f-df22-4f43-9048-ff16ebcdec65
group: NACOS_MICROSERVICE_GROUP
网关的路由配置采用nacos远程配置,在nacos控制台开发环境中新增api-gateway.yaml配置集,配置组为 TEST_GROUP,配置内容如下:
zuul:
routes:
application1:
stripPrefix: false
path: /application1/**
将请求为 /application1/
开头的请求路由至 application1
服务
api-gateway启动
注意在启动类上使用@EnableZuulProxy
注解标识此工程为Zuul网关,启动类代码如下:
package com.ygl.microservice.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
* TODO
*
* @author ygl
* @version V1.0
* @since 2021-05-14 18:27
**/
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ApiGatewayBootstrap {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayBootstrap.class, args);
}
}
当 Service1Bootstrap
启动后,应用 api-gateway
将出现在 Nacos 服务列表中。
通过网关(api-gateway)请求Application1应用,Application1的业务实现又贯穿service1、service2,访问
http://127.0.0.1:56010/application1/service ,将得到如下结果:
源码地址:https://github.com/ygl01/nacos.git
这个源码里有三个不同的父项目,大家注意区分,而且记得更改nacos服务器地址。
好了,今天的分享就到这吧,今天这篇分享的nacos的配置中心和服务注册与发现中心。
那些有分享的不对的地方,还恳请大家能够指正哦。
大家记得一键三连哦,转发 点赞 评论。
我就是小y;我们下期见。
更多推荐
所有评论(0)