Nacos搭建流程 顶

  • 2019 年 12 月 16 日
  • 笔记

要使用nacos,我们首先得下载它的服务端,下载地址https://github.com/alibaba/nacos/releases

根据你的Spring Cloud Alibaba版本来下载需要使用的版本

我这里是tar.gz的,下载完成后,解压,进入bin目录

执行sh startup.sh -m standalone

通过docker安装nacos服务端

docker pull nacos/nacos-server:1.1.3

docker run -d –name nacos -p 8848:8848 –env MODE=standalone nacos/nacos-server:1.1.3

然后通过浏览器访问http://127.0.0.1:8848/nacos/

此时界面如图所示

输入账号nacos,密码nacos后,进入管理界面

搭建一个Spring Cloud Alibaba项目,在父项目中,Springboot版本2.1.7,SpringCloud版本Greenwich.SR2,SpringCloudAlibaba版本2.1.1.RELEASE

<spring-cloud.version>Greenwich.SR2</spring-cloud.version>  <spring-cloud-alibaba.version>2.1.1.RELEASE</spring-cloud-alibaba.version>
<dependencyManagement>     <dependencies>        <dependency>           <groupId>org.springframework.cloud</groupId>           <artifactId>spring-cloud-dependencies</artifactId>           <version>${spring-cloud.version}</version>           <type>pom</type>           <scope>import</scope>        </dependency>        <dependency>           <groupId>com.alibaba.cloud</groupId>           <artifactId>spring-cloud-alibaba-dependencies</artifactId>           <version>${spring-cloud-alibaba.version}</version>           <type>pom</type>           <scope>import</scope>        </dependency>     </dependencies>  </dependencyManagement>

在具体的子项目中放入如下依赖

<dependency>     <groupId>com.alibaba.cloud</groupId>     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>  </dependency>

添加配置

spring:    cloud:      nacos:        discovery:          server-addr: 127.0.0.1:8848    application:      name: user

启动项目,端口8080,在管理界面中可以看到

我们的项目已经被注册进来了。现在我们来建一个类似的项目,端口号8081,编写一个测试Controller,来查找之前的user项目。

@RestController  public class TestController {      /**       * 无论使用哪种注册中心(Eureka,Zookeeper,Consul),该DiscoveryClient是通用的       * 它是一个接口       */      @Autowired      private DiscoveryClient discoveryClient;        @GetMapping("/test")      public List<ServiceInstance> findUser() {          return discoveryClient.getInstances("user");      }  }

运行后,访问如下

如果user启动多个实例,这里也可以获取多个user的信息

现在我们在user模块中增加一个Controller,用另外一个模块使用RestTemplate来调用这个Controller.

@RestController  public class TestController {        @GetMapping("/find")      public String findStr() {          return "春秋一统";      }  }

在调用模块中使用RestTemplate来调用,我们之前发现在discoveryClient.getInstances("user")返回List中有一个uri的属性是我们需要的,我们再拼接上/find就是我们需要的Rest API。

@Slf4j  @Service  public class ConnectServer {      @Autowired      private DiscoveryClient discoveryClient;      private RestTemplate restTemplate = new RestTemplate();        @PostConstruct      public void trace() {          List<ServiceInstance> instances = discoveryClient.getInstances("user");          String targetUrl = instances.stream().map(instance -> instance.getUri().toString() + "/find")                  .findFirst()                  .orElseThrow(() -> new RuntimeException("当前没有实例"));          String result = restTemplate.getForObject(targetUrl, String.class);          log.info(result);      }  }

运行结果(部分日志)

2019-12-06 23:09:12.764 INFO 847 — [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 563 ms 2019-12-06 23:09:18.229 INFO 847 — [ main] c.cgc.cloud.nacos.service.ConnectServer : 春秋一统 2019-12-06 23:09:18.235 WARN 847 — [ main] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources.

现在我们要整合Ribbon来负载均衡

先在调用模块加入我们需要的Apache HTTPClient依赖

<dependency>     <groupId>io.github.openfeign</groupId>     <artifactId>feign-httpclient</artifactId>  </dependency>

给RestTemplate增加连接池,连接次数和超时时间。再打上Ribbon特有的标签@LoadBalanced

@Configuration  public class RestTemplateConfig {     @LoadBalanced     @Bean     public RestTemplate restTemplate() {        PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager();        //连接池最大连接数        pollingConnectionManager.setMaxTotal(400);        pollingConnectionManager.setDefaultMaxPerRoute(200);          HttpClientBuilder httpClientBuilder = HttpClients.custom();        httpClientBuilder.setConnectionManager(pollingConnectionManager);        //连接次数        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true));        HttpClient httpClient = httpClientBuilder.build();          HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(              httpClient);        // 超时时间        clientHttpRequestFactory.setConnectTimeout(5000);        clientHttpRequestFactory.setReadTimeout(5000);        clientHttpRequestFactory.setConnectionRequestTimeout(5000);          RestTemplate restTemplate = new RestTemplate();        restTemplate.setRequestFactory(clientHttpRequestFactory);        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());          return restTemplate;     }  }

为了以示区别,我们在user模块中修改第二个实例的返回字符串

@RestController  public class TestController {        @GetMapping("/find")      public String findStr() {          return "战国一统";      }  }

在调用模块中增加测试Controller

@RestController  public class BalanceController {      @Autowired      private RestTemplate restTemplate;        @GetMapping("/trace")      public String trace() {          return restTemplate.getForObject("http://user/find", String.class);      }  }

启动调用模块

我们不断的点击刷新,它就会不断的出现春秋一统和战国一统返回字符串。

Nacos的环境配置

我们可以在命名空间中设置我们不同环境(比如开发,测试,线上等等)的配置,它们是相互隔离的,互不影响。

在项目中配置如下,加入我们现在要把项目配置到开发环境中

spring:    cloud:      nacos:        discovery:          server-addr: 127.0.0.1:8848          namespace: 9257bc96-8af7-4737-9ce1-a63da2ba2af7    application:      name: user

这里需要注意的就是,我们在填写namespace的时候一定要配置它的命名空间ID,而不能配它的名称,比如dev。

项目启动后,我们可以看到我们的服务现在是在dev的服务列表中.

我们还可以配置它到集群中心

spring:    cloud:      nacos:        discovery:          server-addr: 127.0.0.1:8848          namespace: 9257bc96-8af7-4737-9ce1-a63da2ba2af7          cluster-name: GuangZhou    application:      name: user

启动后,点击详情,可以看到

Nacos配置中心

pom

在子项目中添加依赖

<dependency>     <groupId>com.alibaba.cloud</groupId>     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>  </dependency>

增加bootstrap.yml,添加如下配置(我这里是将tomcat改成了undertow,关于此处说明可以参考Feign HTTP连接的几点建议 )

Spring:    cloud:      nacos:        discovery:          server-addr: 127.0.0.1:8848  #        namespace: 9257bc96-8af7-4737-9ce1-a63da2ba2af7  #        cluster-name: GuangZhou        config:          server-addr: 127.0.0.1:8848          file-extension: yaml    application:      name: user    profiles:      active: dev  server:    port: 8082    undertow:      # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程      # 不要设置过大,如果过大,启动项目会报错:打开文件数过多      io-threads: 16      # 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程      # 它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8      worker-threads: 256      # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理      # 每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可      buffer-size: 1024      # 是否分配的直接内存(NIO直接分配的堆外内存)      direct-buffers: true

在nacos服务台中进行如下操作

点+号,进入如下界面

然后填入数据

Data ID这里需要将Springboot的项目名称与开发环境名称用"-"连接用.yaml后缀名结尾,配置格式选择yaml,配置内容可以放入你对数据库连接,zipkin,mq,mybatis等等各种配置。

点发布返回后,就可以看到该配置列表

启动Springboot项目,从日志可以看到它会先把配置文件给拉取下来

2019-12-09 14:19:29.242 INFO [user,,,] 2129 — [ main] c.a.c.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: 'user-dev.yaml', group: 'DEFAULT_GROUP', data: logging: level: root: info com.cloud: debug file: logs/${spring.application.name}.log spring: zipkin: base-url: http://192.168.1.219:9411 enabled: true sender: type: web sleuth: sampler: probability: 1.0

生产环境的集群改造

nacos本身是使用derby来做数据持久化的,具体查看derby数据方式如下。

关闭nacos

sh shutdown.sh

使用IDEA来连接nacos,打开database工具,点+号

选择Derby(Embedded)

如果没有驱动的话,需要先下载驱动。

找到nacos安装目录/data/derby-data,使用用户名nacos,密码nacos,点Test Connection按钮,出现Successful,表示连接成功。

此后可以看到包含这样一些表的数据库

点开CONFIG_INFO表可以看到我们之前配置中心的配置信息

考虑到Derby的单节点性,生产环境需使用MySQL作为后端存储,因此需要搭建MySQL。生产中,MySQL建议至少主备模式,高可用MySQL更佳。关于高可用的mysql集群可以参考CentOS 7 Galera Cluster安装全攻略 ,主从的可以参考Docker安装mysql8主从结构 版本选择5.7就好。

生产环境部署架构图

这里5.7和8.0就在于他们的驱动不同。8.0的驱动下载地址为https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar