写点什么

Docker 下的 Nacos 环境开发

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:5183 字

    阅读完需:约 17 分钟

echo "Starting nacos"n && \


cd ~/nacos/bin && \


./startup.sh -m standalone && \


cd ../logs && \


tail -f start.out


有两个重要信息需要注意:


  1. nacos 的官方参考启动命令是./startup.sh -m standalone,这个命令会将 jvm 的输出重定向到 start.out 文件,也就是说 nacos 的 JVM 进程是在后台运行的,不会占用控制台(相比之下,spring boot 应用使用 java -jar 启动时会占用控制台),对于 docker 来说,容器内的进程如果不占用控制台,docker 就认为该容器已经结束工作,就会停止该容器,所以,为了避免 nacos 在 docker 刚刚启动就退出,需要用 tail -f start.out 来占领控制台;

  2. 用 tail -f start.out 来占领控制台可以避免容器刚刚启动就退出,但也有个弊端,就是容器中有了多个进程,并且 nacos 进程的 PID 不是 1,所以在执行 docker stop 命令时,结束进程的信号量不会到 nacos 进程,而是去了 PID 等于 1 的进程,所以 nacos 进程不会立即退出,只能等到 30 秒后被强制 kill,这个问题最好的解法是修改 nacos 的 startup.sh,让 nacos 进程始终保持在控制台,不要重定向到后台,但这样就导致 Dockerfile 不好处理了,每次下载和解压了 nacos 安装包后,都要用本地的 startup.sh 去替换原有的,这样做的话,如果 nacos 升级版本,这边本地的 startup.sh 也要随之更新,很是麻烦…

构建镜像

  1. Dockerfile 和 docker-entrypoint.sh 文件准备好之后放在同一个目录,执行以下命令构建镜像:


docker build -t bolingcavalry/nacossimpleprovider:1.0-SNAPSHOT


  1. 如果您在 hub.docker.com 已经注册,可以执行以下命令将本地镜像上传到 hub.docker.com ,这样任何人都可以下载使用该镜像了:


docker push bolingcavalry/nacossimpleprovider:1.0-SNAPSHOT


Nacos 镜像的制作已经完成,接下来制作一个 java 应用的镜像:服务提供者;

java 应用的父工程

接下来要开发的 simple-provider 和 simple-consumer 两个应用都是 java 应用,为了管理方便,做一个基于 maven 的父工程,再将 simple-provider 和 simple-consumer 以 module 的形式加入到这个父工程中;


  1. 基于 maven 创建父工程,名为 nacosdemo,其 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>


<modules>


<module>simpleconsumer</module>


<module>simpleprovider</module>


</modules>


<parent>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-parent</artifactId>


<version>2.0.5.RELEASE</version>


</parent>


<groupId>com.bolingcavalry</groupId>


<artifactId>nacosdemo</artifactId>


<packaging>pom</packaging>


<version>1.0-SNAPSHOT</version>


<properties>


<java.version>1.8</java.version>


<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>


<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>


<java.version>1.8</java.version>


<spring.boot.version>2.0.5.RELEASE</spring.boot.version>


<spring.cloud.version>Finchley.SR1</spring.cloud.version>


<spring.cloud.alibaba.version>0.2.2.RELEASE</spring.cloud.alibaba.version>


</properties>


<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>org.springframework.cloud</groupId>


<artifactId>spring-cloud-alibaba-dependencies</artifactId>


<version>${spring.cloud.alibaba.version}</version>


<type>pom</type>


<scope>import</scope>


</dependency>


</dependencies>


</dependencyManagement>


<build>


<plugins>


<plugin>


<groupId>org.apache.maven.plugins</groupId>


<artifactId>maven-compiler-plugin</artifactId>


<configuration>


<source>${java.version}</source>


<target>${java.version}</target>


<encoding>${project.build.sourceEncoding}</encoding>


</configuration>


</plugin>


</plugins>


</build>


</project>


可见这是个普通的父工程,里面对 spring cloud 和 spring cloud alibaba 的版本做了控制,避免子工程还要各种指定版本的繁琐操作;

制作服务提供者镜像

simple-provider 是个 java web 应用,使用了 spring cloud alibaba 的依赖库之后可以使用 Nacos 的注册发现服务,整个工程的开发步骤如下:


  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>nacosdemo</artifactId>


<groupId>com.bolingcavalry</groupId>


<version>1.0-SNAPSHOT</version>


</parent>


<modelVersion>4.0.0</modelVersion>


<artifactId>simpleprovider</artifactId>


<dependencies>


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-web</artifactId>


</dependency>


<dependency>


<groupId>org.springframework.cloud</groupId>


<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>


</dependency>


</dependencies>


<build>


<plu


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


gins>


<plugin>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-maven-plugin</artifactId>


</plugin>


<plugin>


<groupId>com.google.cloud.tools</groupId>


<artifactId>jib-maven-plugin</artifactId>


<version>1.3.0</version>


<configuration>


<from>


<image>openjdk:8u201-jdk-alpine3.9</image>


</from>


<to>


<!--镜像名称和 tag,使用了 mvn 内置变量{project.version}-->


<image>bolingcavalry/nacos{project.version}</image>


</to>


<container>


<jvmFlags>


<jvmFlag>-Xms1g</jvmFlag>


<jvmFlag>-Xmx1g</jvmFlag>


</jvmFlags>


</container>


</configuration>


</plugin>


</plugins>


</build>


</project>


上述内容有两点需要注意:


a. 依赖 spring-cloud-starter-alibaba-nacos-discovery,这样可以用上 spring cloud nacos 的服务;


b. 使用了 maven 插件 jib-maven-plugin,用于将应用构建成 docker 镜像,此插件相关的详情请参考《Docker与Jib(maven插件版)实战》


2. 配置文件 application.properties,配置应用名称和 nacos 地址,注意这里 nacos 地址配置的是 nacoshost,对应的是后面 docker-compose.yml 中的 link 参数:


spring.application.name=simple-provider


spring.cloud.nacos.discovery.server-addr=nacoshost:8848


  1. 应用启动类 SimpleProviderApplication ,配置了注解 EnableDiscoveryClient,用于启动注册发现服务:


package simpleprovider;


import org.springframework.boot.SpringApplication;


import org.springframework.boot.autoconfigure.SpringBootApplication;


import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@EnableDiscoveryClient


@SpringBootApplication


public class SimpleProviderApplication {


public static void main(String[] args) {


SpringApplication.run(SimpleProviderApplication.class, args);


}


}


  1. 增加一个提供 http 服务的 controller 类 ProviderController:


package simpleprovider.controller;


import org.springframework.web.bind.annotation.PathVariable;


import org.springframework.web.bind.annotation.RequestMapping;


import org.springframework.web.bind.annotation.RequestMethod;


import org.springframework.web.bind.annotation.RestController;


import java.text.SimpleDateFormat;


import java.util.Date;


/**


  • @Description: 提供 web 服务的 controller

  • @author: willzhao E-mail: zq2599@gmail.com

  • @date: 2019/7/28 11:08


*/


@RestController


public class ProviderController {


@RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)


public String hello(@PathVariable("name") String name){


return "hello " + name + ", " + new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date());


}


}


  1. 以上就是 simple-provider 的所有源码了,在 pom.xml 所在目录执行以下命令,即可构建 docker 镜像,存入本地仓库:


mvn compile jib:dockerBuild

制作服务消费者镜像

simple-consumer 是个 java web 应用,启动后对外提供 http 服务,响应的时候,通过 nacos 取得 simple-provider 的地址,然后向 simple-provider 发请求,将响应返回给浏览器:


  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>nacosdemo</artifactId>


<groupId>com.bolingcavalry</groupId>


<version>1.0-SNAPSHOT</version>


</parent>


<modelVersion>4.0.0</modelVersion>


<artifactId>simpleconsumer</artifactId>


<dependencies>


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-web</artifactId>


</dependency>


<dependency>


<groupId>org.springframework.cloud</groupId>


<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>


</dependency>


</dependencies>


<build>


<plugins>


<plugin>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-maven-plugin</artifactId>


</plugin>


<plugin>


<groupId>com.google.cloud.tools</groupId>


<artifactId>jib-maven-plugin</artifactId>


<version>1.3.0</version>


<configuration>


<from>


<image>openjdk:8u201-jdk-alpine3.9</image>


</from>


<to>


<!--镜像名称和 tag,使用了 mvn 内置变量{project.version}-->


<image>bolingcavalry/nacos{project.version}</image>


</to>


<container>


<jvmFlags>


<jvmFlag>-Xms1g</jvmFlag>


<jvmFlag>-Xmx1g</jvmFlag>


</jvmFlags>


<ports>


<port>8080</port>


</ports>


</container>


</configuration>


</plugin>


</plugins>


</build>


</project>


  1. 配置文件 application.properties,配置应用名称和 nacos 地址,注意这里 nacos 地址配置的是 nacoshost,对应的是后面 docker-compose.yml 中的 link 参数:


spring.application.name=simple-consumer


spring.cloud.nacos.discovery.server-addr=nacoshost:8848


  1. 应用启动类 SimpleConsumerApplication,配置了注解 EnableDiscoveryClient,用于启动注册发现服务:


package com.bolingcavalry.simpleconsumer;


import org.springframework.boot.SpringApplication;


import org.springframework.boot.autoconfigure.SpringBootApplication;


import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@EnableDiscoveryClient


@SpringBootApplication


public class SimpleConsumerApplication {


public static void main(String[] args) {


SpringApplication.run(SimpleConsumerApplication.class, args);


}


}


  1. 增加一个提供 http 服务的 controller 类 ConsumerController,通过 LoadBalancerClient 取得 simple-provider 的服务地址,然后发请求过去 :


package com.bolingcavalry.simpleconsumer.controller;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.cloud.client.ServiceInstance;


import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;


import org.springframework.web.bind.annotation.RequestMapping;


import org.springframework.web.bind.annotation.RestController;


import org.springframework.web.client.RestTemplate;


import java.text.SimpleDateFormat;


import java.util.Date;


/**


  • @Description: 提供 web 服务的 controller

  • @author: willzhao E-mail: zq2599@gmail.com

  • @date: 2019/7/28 11:08


*/


@RestController


public class ConsumerController {


@Autowired


LoadBalancerClient loadBalancerClient;


@RequestMapping("/test")


public String test(){


//根据应用名称取得实例对象


ServiceInstance serviceInstance = loadBalancerClient.choose("simple-provider");

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Docker下的Nacos环境开发