├── docker ├── dubbo-sample │ ├── README.md │ ├── Chart.yaml │ └── templates │ │ ├── consumer-service.yaml │ │ ├── zookeeper-service.yaml │ │ ├── zookeeper-deployment.yaml │ │ ├── producer-deployment.yaml │ │ └── consumer-deployment.yaml ├── docker-compose.yml ├── docker-compose-v3.yml └── docker-compose-acs.yml ├── service-consumer ├── src │ └── main │ │ ├── resources │ │ ├── application.properties │ │ └── services.xml │ │ └── java │ │ └── com │ │ └── example │ │ └── service │ │ └── consumer │ │ └── Application.java ├── Dockerfile └── pom.xml ├── yunqi ├── arch.png ├── logos.png ├── consumer1.png ├── consumer2.png └── README.md ├── service-producer ├── Dockerfile ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── service │ │ │ └── producer │ │ │ ├── GreetingsImpl.java │ │ │ └── Application.java │ │ └── resources │ │ └── services.xml └── pom.xml ├── service-api ├── src │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── service │ │ └── Greetings.java └── pom.xml ├── .gitignore ├── pom.xml └── README.md /docker/dubbo-sample/README.md: -------------------------------------------------------------------------------- 1 | This chart was created by Kompose 2 | -------------------------------------------------------------------------------- /service-consumer/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=${SERVER_PORT:0} -------------------------------------------------------------------------------- /yunqi/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binblee/dubbo-docker/HEAD/yunqi/arch.png -------------------------------------------------------------------------------- /yunqi/logos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binblee/dubbo-docker/HEAD/yunqi/logos.png -------------------------------------------------------------------------------- /yunqi/consumer1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binblee/dubbo-docker/HEAD/yunqi/consumer1.png -------------------------------------------------------------------------------- /yunqi/consumer2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binblee/dubbo-docker/HEAD/yunqi/consumer2.png -------------------------------------------------------------------------------- /service-consumer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre 2 | VOLUME /tmp 3 | COPY target/*.jar app.jar 4 | RUN sh -c 'touch /app.jar' 5 | CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] -------------------------------------------------------------------------------- /service-producer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre 2 | VOLUME /tmp 3 | COPY target/*.jar /app.jar 4 | RUN sh -c 'touch /app.jar' 5 | CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] -------------------------------------------------------------------------------- /docker/dubbo-sample/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: dubbo-sample 2 | description: A generated Helm Chart for dubbo-sample from Skippbox Kompose 3 | version: 0.0.1 4 | keywords: 5 | - dubbo-sample 6 | sources: 7 | home: 8 | -------------------------------------------------------------------------------- /service-api/src/main/java/com/example/service/Greetings.java: -------------------------------------------------------------------------------- 1 | package com.example.service; 2 | 3 | /** 4 | * Created by libin on 9/19/16. 5 | */ 6 | public interface Greetings { 7 | String say(String name); 8 | } 9 | -------------------------------------------------------------------------------- /service-producer/src/main/java/com/example/service/producer/GreetingsImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.service.producer; 2 | 3 | import com.example.service.Greetings; 4 | 5 | /** 6 | * Created by libin on 9/19/16. 7 | */ 8 | public class GreetingsImpl implements Greetings { 9 | public String say(String name) { 10 | return "Greetings from " + name; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | services: 3 | zookeeper: 4 | image: 'registry.aliyuncs.com/acs-sample/zookeeper:3.4.8' 5 | hostname: zookeeper 6 | producer: 7 | image: 'producer:latest' 8 | environment: 9 | - ZOOKEEPER_SERVER=zookeeper 10 | consumer: 11 | image: 'consumer:latest' 12 | environment: 13 | - ZOOKEEPER_SERVER=zookeeper 14 | - SERVER_PORT=8899 15 | ports: 16 | - 8899:8899 17 | -------------------------------------------------------------------------------- /docker/dubbo-sample/templates/consumer-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f docker-compose-v3.yml -c -o dubbo-sample 6 | kompose.version: 1.14.0 () 7 | creationTimestamp: null 8 | labels: 9 | io.kompose.service: consumer 10 | name: consumer 11 | spec: 12 | ports: 13 | - name: "8899" 14 | port: 8899 15 | targetPort: 8899 16 | selector: 17 | io.kompose.service: consumer 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /docker/dubbo-sample/templates/zookeeper-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f docker-compose-v3.yml -c -o dubbo-sample 6 | kompose.version: 1.14.0 () 7 | creationTimestamp: null 8 | labels: 9 | io.kompose.service: zookeeper 10 | name: zookeeper 11 | spec: 12 | ports: 13 | - name: "2181" 14 | port: 2181 15 | targetPort: 2181 16 | selector: 17 | io.kompose.service: zookeeper 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /docker/docker-compose-v3.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | zookeeper: 4 | image: 'registry.aliyuncs.com/acs-sample/zookeeper:3.4.8' 5 | ports: 6 | - '2181' 7 | producer: 8 | image: 'registry.cn-hangzhou.aliyuncs.com/jingshanlb/dubbo-springboot-producer:latest' 9 | environment: 10 | - ZOOKEEPER_SERVER=zookeeper 11 | consumer: 12 | image: 'registry.cn-hangzhou.aliyuncs.com/jingshanlb/dubbo-springboot-consumer:latest' 13 | environment: 14 | - ZOOKEEPER_SERVER=zookeeper 15 | - SERVER_PORT=8899 16 | ports: 17 | - '8899' 18 | -------------------------------------------------------------------------------- /docker/docker-compose-acs.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | services: 3 | zookeeper: 4 | image: 'registry.aliyuncs.com/acs-sample/zookeeper:3.4.8' 5 | hostname: zookeeper 6 | producer: 7 | image: 'registry.cn-hangzhou.aliyuncs.com/jingshanlb/dubbo-springboot-producer:latest' 8 | environment: 9 | - ZOOKEEPER_SERVER=zookeeper 10 | consumer: 11 | image: 'registry.cn-hangzhou.aliyuncs.com/jingshanlb/dubbo-springboot-consumer:latest' 12 | environment: 13 | - ZOOKEEPER_SERVER=zookeeper 14 | - SERVER_PORT=8899 15 | labels: 16 | aliyun.routing.port_8899: http://ds-consumer 17 | -------------------------------------------------------------------------------- /service-producer/src/main/java/com/example/service/producer/Application.java: -------------------------------------------------------------------------------- 1 | package com.example.service.producer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ImportResource; 6 | 7 | /** 8 | * Created by libin on 9/19/16. 9 | */ 10 | @SpringBootApplication 11 | @ImportResource({"classpath:services.xml"}) 12 | public class Application { 13 | public static void main(String[] args) throws Exception{ 14 | SpringApplication.run(Application.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven 2 | 3 | target/ 4 | pom.xml.tag 5 | pom.xml.releaseBackup 6 | pom.xml.versionsBackup 7 | pom.xml.next 8 | release.properties 9 | dependency-reduced-pom.xml 10 | buildNumber.properties 11 | .mvn/timing.properties 12 | 13 | # Java 14 | *.class 15 | 16 | # Mobile Tools for Java (J2ME) 17 | .mtj.tmp/ 18 | 19 | # Package Files # 20 | *.jar 21 | *.war 22 | *.ear 23 | 24 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 25 | hs_err_pid* 26 | 27 | # IDEA 28 | .idea 29 | *.iml 30 | 31 | # atom 32 | .classpath 33 | .project 34 | .settings 35 | 36 | # Others 37 | *~ 38 | .DS_Store 39 | -------------------------------------------------------------------------------- /docker/dubbo-sample/templates/zookeeper-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f docker-compose-v3.yml -c -o dubbo-sample 6 | kompose.version: 1.14.0 () 7 | creationTimestamp: null 8 | labels: 9 | io.kompose.service: zookeeper 10 | name: zookeeper 11 | spec: 12 | replicas: 1 13 | strategy: {} 14 | template: 15 | metadata: 16 | creationTimestamp: null 17 | labels: 18 | io.kompose.service: zookeeper 19 | spec: 20 | containers: 21 | - image: registry.aliyuncs.com/acs-sample/zookeeper:3.4.8 22 | name: zookeeper 23 | ports: 24 | - containerPort: 2181 25 | resources: {} 26 | restartPolicy: Always 27 | status: {} 28 | -------------------------------------------------------------------------------- /service-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dubbo-service 7 | com.example 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dubbo-service-api 13 | 14 | 15 | com.alibaba 16 | dubbo 17 | 2.5.3 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docker/dubbo-sample/templates/producer-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f docker-compose-v3.yml -c -o dubbo-sample 6 | kompose.version: 1.14.0 () 7 | creationTimestamp: null 8 | labels: 9 | io.kompose.service: producer 10 | name: producer 11 | spec: 12 | replicas: 1 13 | strategy: {} 14 | template: 15 | metadata: 16 | creationTimestamp: null 17 | labels: 18 | io.kompose.service: producer 19 | spec: 20 | containers: 21 | - env: 22 | - name: ZOOKEEPER_SERVER 23 | value: zookeeper 24 | image: registry.cn-hangzhou.aliyuncs.com/jingshanlb/dubbo-springboot-producer:latest 25 | name: producer 26 | resources: {} 27 | restartPolicy: Always 28 | status: {} 29 | -------------------------------------------------------------------------------- /service-consumer/src/main/resources/services.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.example 8 | dubbo-service 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 1.4.0.RELEASE 15 | 16 | 17 | 18 | service-api 19 | service-producer 20 | service-consumer 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docker/dubbo-sample/templates/consumer-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f docker-compose-v3.yml -c -o dubbo-sample 6 | kompose.version: 1.14.0 () 7 | creationTimestamp: null 8 | labels: 9 | io.kompose.service: consumer 10 | name: consumer 11 | spec: 12 | replicas: 1 13 | strategy: {} 14 | template: 15 | metadata: 16 | creationTimestamp: null 17 | labels: 18 | io.kompose.service: consumer 19 | spec: 20 | containers: 21 | - env: 22 | - name: SERVER_PORT 23 | value: "8899" 24 | - name: ZOOKEEPER_SERVER 25 | value: zookeeper 26 | image: registry.cn-hangzhou.aliyuncs.com/jingshanlb/dubbo-springboot-consumer:latest 27 | name: consumer 28 | ports: 29 | - containerPort: 8899 30 | resources: {} 31 | restartPolicy: Always 32 | status: {} 33 | -------------------------------------------------------------------------------- /service-producer/src/main/resources/services.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /service-consumer/src/main/java/com/example/service/consumer/Application.java: -------------------------------------------------------------------------------- 1 | package com.example.service.consumer; 2 | 3 | import com.example.service.Greetings; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.context.annotation.ImportResource; 9 | import org.springframework.context.support.ClassPathXmlApplicationContext; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | 14 | @SpringBootApplication 15 | @ImportResource({"classpath:services.xml"}) 16 | @RestController 17 | public class Application { 18 | 19 | @Autowired 20 | private ApplicationContext context; 21 | 22 | public static void main(String[] args){ 23 | SpringApplication.run(Application.class,args); 24 | } 25 | 26 | @RequestMapping("/") 27 | public String greetings(){ 28 | Greetings greetingService = (Greetings)context.getBean("greetingService"); 29 | String result = greetingService.say("Dubbo Docker"); 30 | return result; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /service-producer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.example 7 | dubbo-service-producer 8 | 1.0-SNAPSHOT 9 | jar 10 | 11 | service-producer 12 | Demo project for Spring Boot 13 | 14 | 15 | dubbo-service 16 | com.example 17 | 1.0-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | 39 | com.example 40 | dubbo-service-api 41 | 1.0-SNAPSHOT 42 | 43 | 44 | com.alibaba 45 | dubbo 46 | 2.5.3 47 | 48 | 49 | spring 50 | org.springframework 51 | 52 | 53 | 54 | 55 | com.github.sgroschupf 56 | zkclient 57 | 0.1 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-maven-plugin 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /service-consumer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.example 7 | dubbo-service-consumer 8 | 1.0-SNAPSHOT 9 | jar 10 | 11 | service-consumer 12 | Demo project for Spring Boot 13 | 14 | 15 | dubbo-service 16 | com.example 17 | 1.0-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | 39 | com.example 40 | dubbo-service-api 41 | 1.0-SNAPSHOT 42 | 43 | 44 | com.alibaba 45 | dubbo 46 | 2.5.3 47 | 48 | 49 | spring 50 | org.springframework 51 | 52 | 53 | 54 | 55 | com.github.sgroschupf 56 | zkclient 57 | 0.1 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-maven-plugin 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dubbo in Docker Example 2 | 3 | Dubbo running in Docker, packaged as a springboot application. 4 | 5 | ## Services 6 | 7 | This demo consistes three services: 8 | 9 | - a zookeper instance 10 | - a service producer 11 | - a service consumer 12 | 13 | The service producer exposes a ```Greeting``` service through RPC, 14 | service consumer access the producer. 15 | 16 | ## Zookeeper 17 | 18 | Run a docker image. 19 | 20 | ## Service Producer 21 | 22 | Code in [service-producer](service-producer). API defined in [service-api](service-api). 23 | 24 | Build docker image: 25 | 26 | ``` 27 | cd service-producer 28 | mvn package 29 | docker build -t producer . 30 | ``` 31 | 32 | ## Service Consumer 33 | 34 | Code in [service-consumer](service-consumer). 35 | 36 | Build docker image: 37 | 38 | ``` 39 | cd service-consumer 40 | mvn package 41 | docker build -t consumer . 42 | ``` 43 | 44 | ## Run 45 | 46 | Use docker-compose command to run it. 47 | 48 | ``` 49 | cd docker 50 | docker-compose up -d 51 | ``` 52 | 53 | Verify that all works: 54 | ``` 55 | $curl http://localhost:8899/ 56 | Greetings from Dubbo Docker 57 | ``` 58 | 59 | ## Run it on Alibaba Cloud 60 | 61 | Use [docker/docker-compose-acs.yml](docker/docker-compose-acs.yml) to deploy this application to 62 | Aliyun Container Service (Alibaba Cloud) swarm cluster. 63 | 64 | 2017.11.30 Update: 65 | Add compose v3 sample yml file: [docker/docker-compose-v3.yml](docker/docker-compose-v3.yml) 66 | 67 | 68 | 69 | ### Deploy the application to Kubernetes 70 | 71 | 2018.8.17 Update: 72 | 73 | You can user helm to install this sample in a Kubernetes cluster. 74 | 75 | ``` 76 | $ cd docker 77 | $ helm install -n dubbo-sample dubbo-sample 78 | ``` 79 | 80 | 81 | 82 | Check helm status 83 | 84 | ``` 85 | $ helm list 86 | NAME REVISION UPDATED STATUS CHART NAMESPACE 87 | dubbo-sample 1 Fri Aug 17 07:27:00 2018 DEPLOYED dubbo-sample-0.0.1 default 88 | ``` 89 | 90 | 91 | 92 | Check kubernetes and service status: 93 | 94 | ``` 95 | $ kubectl get po,svc 96 | NAME READY STATUS RESTARTS AGE 97 | pod/consumer-749bf8484d-js6wf 1/1 Running 0 7m 98 | pod/producer-b4f76b6c7-b8jhg 1/1 Running 0 7m 99 | pod/zookeeper-8455f4fdc9-ht9ms 1/1 Running 0 7m 100 | 101 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 102 | service/consumer ClusterIP 172.19.10.188 8899/TCP 7m 103 | service/kubernetes ClusterIP 172.19.0.1 443/TCP 45d 104 | service/zookeeper ClusterIP 172.19.10.253 2181/TCP 7m 105 | ``` 106 | 107 | 108 | 109 | Expose consumer a public IP, or add ingress to it, Visit consumer via browser, you will see the greetings. 110 | 111 | ``` 112 | Greetings from Dubbo Docker 113 | ``` 114 | 115 | 116 | 117 | This sample tested on Aliyun Container Service for Kubernetes. -------------------------------------------------------------------------------- /yunqi/README.md: -------------------------------------------------------------------------------- 1 | # 在Docker中运行Dubbo应用 2 | 3 | ## 更新历史 4 | - 2017.11.30 增加利用v3版本compose文件部署示例。 5 | 6 | ## Dubbo概述 7 | 8 | ![](logos.png) 9 | 10 | Dubbo是阿里开源的一个分布式服务框架,在国内粉丝很多。[官网](http://dubbo.io)上的介绍是: 11 | 12 | >DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。 13 | > 14 | 15 | Dubbo的文档很完整,网络上资源也很多,这里就不再重复了。本文做这样一个尝试,将一个Dubbo应用容器化,部署到阿里云的容器服务上。 16 | 17 | ## 极简Dubbo应用结构 18 | 19 | 在Dubbo世界里,服务调用方和服务提供方通过Dubbo的发现机制互相发现。一个最小的Dubbo应用包含如下三个服务: 20 | 21 | - 服务提供者 22 | - 服务调用方 23 | - 发现机制(例如zookeeper) 24 | 25 | ![](arch.png) 26 | 27 | zookeeper已经有Docker镜像了,下面我们就会用[Spring Boot](https://projects.spring.io/spring-boot/)开发服务提供方Service Producer和服务调用方Service Consumer。 28 | 29 | ## 定义服务接口 30 | 31 | 创建一个Maven模块service-api,定义服务接口。 32 | 33 | ```java 34 | public interface Greetings { 35 | String say(String name); 36 | } 37 | ``` 38 | 这个接口很简单,就是问好。 39 | 40 | 在pom.xml中引入对Dubbo的依赖: 41 | 42 | ```xml 43 | 44 | 45 | com.alibaba 46 | dubbo 47 | 2.5.3 48 | 49 | 50 | ``` 51 | 我们用的是dubbo 2.5.3版本,读者如果愿意尝试更新的版本,可以自行升级。 52 | 53 | ## 服务提供方 Service Producer 54 | 55 | 创建一个Maven模块service-producer,提供服务接口的实现。 56 | 57 | ```java 58 | public class GreetingsImpl implements Greetings { 59 | public String say(String name) { 60 | return "Greetings from " + name; 61 | } 62 | } 63 | ``` 64 | 65 | 为了能找到服务接口模块,需要在pom.xml中定义对service-api的依赖。 66 | 67 | ```xml 68 | 69 | ... 70 | 71 | com.example 72 | dubbo-service-api 73 | 1.0-SNAPSHOT 74 | 75 | 76 | ``` 77 | 78 | Dubbo通过spring xml配置文件的方式声明对zookeeper的访问。在resources目录下创建services.xml,其中最重要的内容是指定zookeeper的地址和端口,为了不把zookeeper的地址写死在配置文件中,我们采用环境变量来指明服务地址。这也是[12 factor](https://12factor.net/)应用的一个推荐实践之一。 79 | 80 | ```xml 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | ``` 89 | xml文件中的其他内容包括指定本服务的侦听端口为```20880```,```GreetingsImpl```类实现的接口API类等。 90 | 91 | 下面要在pom.xml引入dubbo的项目依赖。 92 | 93 | ```xml 94 | 95 | ... 96 | 97 | com.alibaba 98 | dubbo 99 | 2.5.3 100 | 101 | 102 | spring 103 | org.springframework 104 | 105 | 106 | 107 | 108 | com.github.sgroschupf 109 | zkclient 110 | 0.1 111 | 112 | 113 | ``` 114 | 115 | 我们准备用spring 4.x,所以把dubbo中自带的老版本springframework剔除。 116 | 117 | 现在服务的实现类有了,我们需要一个主函数把实现类运行起来。Springboot有一个很好的特性,就是把一个Java应用的所有相关依赖打包成为一个超级JAR包,对于生成Docker镜像来说非常方便。 118 | 119 | 首先在pom.xml中引入springboot依赖。 120 | 121 | ```xml 122 | 123 | 124 | org.springframework.boot 125 | spring-boot-starter-web 126 | 127 | ... 128 | 129 | ``` 130 | 131 | 创建一个Spring主应用。由于Dubbo采用xml配置文件的方式,要通过```@ImportResource```声明加载services.xml配置文件。 132 | 133 | ```java 134 | @SpringBootApplication 135 | @ImportResource({"classpath:services.xml"}) 136 | public class Application { 137 | public static void main(String[] args) throws Exception{ 138 | SpringApplication.run(Application.class, args); 139 | } 140 | } 141 | ``` 142 | 143 | Springboot Web应用启动后会自动侦听8080端口。不过我们在这里没有用到内置的tomcat和8080端口。如果你不喜欢这个多余的tomcat,可以用```spring-boot-starter```替换本文中的```spring-boot-starter-web```项目,但要注意的是,没有tomcat的代码需要增加不退出应用的逻辑。 144 | 145 | ## 服务调用方 Service Consumer 146 | 147 | Service Consumer的结构和Producer的结构类似,也需要在pom.xml中引入对dubbo, service-api和springboot的依赖。在resouces目录下创建services.xml,声明zookeeper的地址和要访问的服务接口: 148 | 149 | ```xml 150 | 151 | 152 | 153 | ``` 154 | 远程调用的服务bean名字为```greetingService```,在下面的代码中要用到。 155 | 156 | 在Application主应用中调用Service Producer。 157 | 158 | ```java 159 | Greetings greetingService = (Greetings)context.getBean("greetingService"); 160 | String result = greetingService.say("Dubbo Docker"); 161 | ``` 162 | 163 | 为了能够用HTTP访问Consumer应用,我们用```@RequestMapping```将context root /映射到方法上。 164 | 165 | ``` 166 | @RequestMapping("/") 167 | public String greetings(){ 168 | ... 169 | ``` 170 | 171 | Consumer启动侦听的端口在resources/application.properties文件中指定: 172 | 173 | ``` 174 | server.port=${SERVER_PORT:0} 175 | ``` 176 | 177 | ## 编译并在本地运行 178 | 179 | 在项目的根目录下运行Maven编译: 180 | 181 | ``` 182 | mvn package 183 | ``` 184 | 185 | 从Docker镜像中启动zookeeper,并把2181端口映射到本机: 186 | 187 | ``` 188 | docker run -d -p 2181:2181 -p 2888:2888 -p 3888:3888 registry.aliyuncs.com/acs-sample/zookeeper:3.4.8 189 | ``` 190 | 191 | 在环境变量中指定zookeeper地址,启动Service Producer。 192 | 193 | ``` 194 | export ZOOKEEPER_SERVER=127.0.0.1 195 | java -jar target/dubbo-service-producer-1.0-SNAPSHOT.jar 196 | ``` 197 | 198 | 启动Service Consumer时除了要指定zookeeper地址外,还要指定consumer自己侦听的地址,本示例中使用的是8899。 199 | 200 | ``` 201 | export ZOOKEEPER_SERVER=127.0.0.1 202 | export SERVER_PORT=8899 203 | java -jar target/dubbo-service-consumer-1.0-SNAPSHOT.jar 204 | ``` 205 | 206 | 访问一下cosumer的HTTP 8899端口,可以看到消息的输出。说明服务调用方从zookeeper中获得了正确的producer的地址,并用dubbo远程调用协议成功调用了producer的GreetingService。 207 | 208 | ``` 209 | $curl http://localhost:8899/ 210 | Greetings from Dubbo Docker 211 | ``` 212 | 213 | ## 构建Docker镜像 214 | 215 | 为Producer和Consumer构建Docker镜像和正常的SpringBoot应用一样,Dockerfile内容如下: 216 | 217 | ``` 218 | FROM openjdk:8-jre 219 | VOLUME /tmp 220 | COPY target/*.jar app.jar 221 | RUN sh -c 'touch /app.jar' 222 | CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 223 | ``` 224 | 225 | 把这个文件分别放在Producer和Consumer的目录下,执行Docker的编译命令即可打包生成容器镜像。 226 | 227 | 在service-producer目录下运行: 228 | 229 | ``` 230 | mvn package 231 | docker build -t producer . 232 | ``` 233 | 234 | 生成service-consumer镜像类似,这里就不重复了。 235 | 236 | 两个镜像生成后,可以用Docker Compose命令启动。对应的docker-compose.yml内容如下: 237 | 238 | ```yaml 239 | version: "2" 240 | services: 241 | zookeeper: 242 | image: 'registry.aliyuncs.com/acs-sample/zookeeper:3.4.8' 243 | hostname: zookeeper 244 | producer: 245 | image: 'producer:latest' 246 | environment: 247 | - ZOOKEEPER_SERVER=zookeeper 248 | consumer: 249 | image: 'consumer:latest' 250 | environment: 251 | - ZOOKEEPER_SERVER=zookeeper 252 | - SERVER_PORT=8899 253 | ports: 254 | - 8899:8899 255 | 256 | ``` 257 | 258 | 在这里把zookeeper容器的主机名hostname设置为```zookeeper```并通过环境变量传给producer和consumer。运行Docker Compose启动三个容器。 259 | 260 | ``` 261 | $docker-compose up -d 262 | Creating docker_consumer_1 263 | Creating docker_zookeeper_1 264 | Creating docker_producer_1 265 | ``` 266 | 267 | 容器启动成功后用同样方式访问8899端口可以看到正确的输出。 268 | 269 | ``` 270 | $curl http://localhost:8899/ 271 | Greetings from Dubbo Docker 272 | ``` 273 | 274 | ## 部署到阿里云容器上 275 | 276 | 好了,至此我们已经成功地在本地Docker环境中运行了Dubbo应用,下面就要将这个应用部署到阿里云容器服务上。 277 | 278 | 首先登陆阿里云Docker镜像仓库,地址在此[https://cr.console.aliyun.com/](https://cr.console.aliyun.com/),创建2个镜像仓库。在本示例中命名为```dubbo-springboot-producer```和```dubbo-springboot-consumer```。 279 | 280 | 创建一个为阿里云部署的模版文件,docker-compose-acs.yml,内容和docker-compose.yml类似。 281 | 282 | ```yaml 283 | version: "2" 284 | services: 285 | zookeeper: 286 | image: 'registry.aliyuncs.com/acs-sample/zookeeper:3.4.8' 287 | hostname: zookeeper 288 | producer: 289 | image: 'registry.cn-hangzhou.aliyuncs.com/${rname}/dubbo-springboot-producer:latest' 290 | environment: 291 | - ZOOKEEPER_SERVER=zookeeper 292 | consumer: 293 | image: 'registry.cn-hangzhou.aliyuncs.com/${rname}/dubbo-springboot-consumer:latest' 294 | environment: 295 | - ZOOKEEPER_SERVER=zookeeper 296 | - SERVER_PORT=8899 297 | labels: 298 | aliyun.routing.port_8899: http://ds-consumer 299 | 300 | ``` 301 | 302 | 这个部署文件和docker-compose.yml内容不同之处在于,所有容器到主机端口映射都去掉了,为了能访问consumer,使用了```aliyun.routing.port_8899```为consumer指定一个子域名。集群部署后可用如下URL访问consumer服务。 303 | 304 | ``` 305 | http://ds-consumer.c67***8cd5.cn-shenzhen.alicontainer.com 306 | ``` 307 | 308 | 登陆阿里云容器服务控制台 [https://cs.console.aliyun.com](https://cs.console.aliyun.com),利用部署模版创建一个新应用,部署模版的内容就是上面docker-compose-acs.yml内容,提示```rname```时输入你的容器仓库用户名,很快应用部署就会成功。 309 | 310 | 在控制台中进入consumer服务页面,找到访问端点: 311 | 312 | ![](consumer1.png) 313 | 314 | 点击地址,可以在浏览器中看到输出: 315 | 316 | ![](consumer2.png) 317 | 318 | 至此,我们成功地在云上运行了Dubbo应用。 319 | 320 | 本文中的compose模版部署为v2版本,如果大家想尝试利用v3版本部署,可以访问[github](https://github.com/binblee/dubbo-docker/blob/master/docker/docker-compose-v3.yml) 321 | 322 | ## 讨论 323 | 324 | 在网上有讨论容器化的Dubbo应用发送的IP地址不对,经实测在Docker 1.12版本下没有这个问题,部署到阿里云容器服务上也正常。本文的示例代码在[github](https://github.com/binblee/dubbo-docker)上,大家可以参考。 325 | 326 | ## 小节 327 | 本文通过Spring Boot构建了一个最小的Dubbo应用,容器化后成功部署到阿里云容器服务上。 328 | --------------------------------------------------------------------------------