在Docker中运行Dubbo应用
更新历史
- 2017.11.30 增加利用v3版本compose文件部署示例。
Dubbo概述
Dubbo是阿里开源的一个分布式服务框架,在国内粉丝很多。官网上的介绍是:
DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。
Dubbo的文档很完整,网络上资源也很多,这里就不再重复了。本文做这样一个尝试,将一个Dubbo应用容器化,部署到阿里云的容器服务上。
极简Dubbo应用结构
在Dubbo世界里,服务调用方和服务提供方通过Dubbo的发现机制互相发现。一个最小的Dubbo应用包含如下三个服务:
- 服务提供者
- 服务调用方
- 发现机制(例如zookeeper)
zookeeper已经有Docker镜像了,下面我们就会用Spring Boot开发服务提供方Service Producer和服务调用方Service Consumer。
定义服务接口
创建一个Maven模块service-api,定义服务接口。
public interface Greetings {String say(String name);
}
这个接口很简单,就是问好。
在pom.xml中引入对Dubbo的依赖:
<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><version>2.5.3</version></dependency>
</dependencies>
我们用的是dubbo 2.5.3版本,读者如果愿意尝试更新的版本,可以自行升级。
服务提供方 Service Producer
创建一个Maven模块service-producer,提供服务接口的实现。
public class GreetingsImpl implements Greetings {public String say(String name) {return "Greetings from " + name;}
}
为了能找到服务接口模块,需要在pom.xml中定义对service-api的依赖。
<dependencies>...<dependency><groupId>com.example</groupId><artifactId>dubbo-service-api</artifactId><version>1.0-SNAPSHOT</version></dependency>
Dubbo通过spring xml配置文件的方式声明对zookeeper的访问。在resources目录下创建services.xml,其中最重要的内容是指定zookeeper的地址和端口,为了不把zookeeper的地址写死在配置文件中,我们采用环境变量来指明服务地址。这也是12 factor应用的一个推荐实践之一。
<dubbo:registry protocol="zookeeper" address="${ZOOKEEPER_SERVER}:2181" /><dubbo:protocol name="dubbo" port="20880" /><dubbo:service interface="com.example.service.Greetings" ref="greetingService"/><bean id="greetingService" class="com.example.service.producer.GreetingsImpl" />
xml文件中的其他内容包括指定本服务的侦听端口为20880
,GreetingsImpl
类实现的接口API类等。
下面要在pom.xml引入dubbo的项目依赖。
<dependencies>...<dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><version>2.5.3</version><exclusions><exclusion><artifactId>spring</artifactId><groupId>org.springframework</groupId></exclusion></exclusions></dependency><dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version></dependency>
我们准备用spring 4.x,所以把dubbo中自带的老版本springframework剔除。
现在服务的实现类有了,我们需要一个主函数把实现类运行起来。Springboot有一个很好的特性,就是把一个Java应用的所有相关依赖打包成为一个超级JAR包,对于生成Docker镜像来说非常方便。
首先在pom.xml中引入springboot依赖。
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
...
创建一个Spring主应用。由于Dubbo采用xml配置文件的方式,要通过@ImportResource
声明加载services.xml配置文件。
@SpringBootApplication
@ImportResource({"classpath:services.xml"})
public class Application {public static void main(String[] args) throws Exception{SpringApplication.run(Application.class, args);}
}
Springboot Web应用启动后会自动侦听8080端口。不过我们在这里没有用到内置的tomcat和8080端口。如果你不喜欢这个多余的tomcat,可以用spring-boot-starter
替换本文中的spring-boot-starter-web
项目,但要注意的是,没有tomcat的代码需要增加不退出应用的逻辑。
服务调用方 Service Consumer
Service Consumer的结构和Producer的结构类似,也需要在pom.xml中引入对dubbo, service-api和springboot的依赖。在resouces目录下创建services.xml,声明zookeeper的地址和要访问的服务接口:
<dubbo:registry protocol="zookeeper" address="${ZOOKEEPER_SERVER}:2181" />
<dubbo:reference id="greetingService" interface="com.example.service.Greetings" />
远程调用的服务bean名字为greetingService
,在下面的代码中要用到。
在Application主应用中调用Service Producer。
Greetings greetingService = (Greetings)context.getBean("greetingService");
String result = greetingService.say("Dubbo Docker");
为了能够用HTTP访问Consumer应用,我们用@RequestMapping
将context root /映射到方法上。
@RequestMapping("/")
public String greetings(){...
Consumer启动侦听的端口在resources/application.properties文件中指定:
server.port=${SERVER_PORT:0}
编译并在本地运行
在项目的根目录下运行Maven编译:
mvn package
从Docker镜像中启动zookeeper,并把2181端口映射到本机:
docker run -d -p 2181:2181 -p 2888:2888 -p 3888:3888 registry.aliyuncs.com/acs-sample/zookeeper:3.4.8
在环境变量中指定zookeeper地址,启动Service Producer。
export ZOOKEEPER_SERVER=127.0.0.1
java -jar target/dubbo-service-producer-1.0-SNAPSHOT.jar
启动Service Consumer时除了要指定zookeeper地址外,还要指定consumer自己侦听的地址,本示例中使用的是8899。
export ZOOKEEPER_SERVER=127.0.0.1
export SERVER_PORT=8899
java -jar target/dubbo-service-consumer-1.0-SNAPSHOT.jar
访问一下cosumer的HTTP 8899端口,可以看到消息的输出。说明服务调用方从zookeeper中获得了正确的producer的地址,并用dubbo远程调用协议成功调用了producer的GreetingService。
$curl http://localhost:8899/
Greetings from Dubbo Docker
构建Docker镜像
为Producer和Consumer构建Docker镜像和正常的SpringBoot应用一样,Dockerfile内容如下:
FROM openjdk:8-jre
VOLUME /tmp
COPY target/*.jar app.jar
RUN sh -c 'touch /app.jar'
CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
把这个文件分别放在Producer和Consumer的目录下,执行Docker的编译命令即可打包生成容器镜像。
在service-producer目录下运行:
mvn package
docker build -t producer .
生成service-consumer镜像类似,这里就不重复了。
两个镜像生成后,可以用Docker Compose命令启动。对应的docker-compose.yml内容如下:
version: "2"
services:zookeeper:image: 'registry.aliyuncs.com/acs-sample/zookeeper:3.4.8'hostname: zookeeperproducer:image: 'producer:latest'environment:- ZOOKEEPER_SERVER=zookeeperconsumer:image: 'consumer:latest'environment:- ZOOKEEPER_SERVER=zookeeper- SERVER_PORT=8899ports:- 8899:8899
在这里把zookeeper容器的主机名hostname设置为zookeeper
并通过环境变量传给producer和consumer。运行Docker Compose启动三个容器。
$docker-compose up -d
Creating docker_consumer_1
Creating docker_zookeeper_1
Creating docker_producer_1
容器启动成功后用同样方式访问8899端口可以看到正确的输出。
$curl http://localhost:8899/
Greetings from Dubbo Docker
部署到阿里云容器上
好了,至此我们已经成功地在本地Docker环境中运行了Dubbo应用,下面就要将这个应用部署到阿里云容器服务上。
首先登陆阿里云Docker镜像仓库,地址在此https://cr.console.aliyun.com/,创建2个镜像仓库。在本示例中命名为dubbo-springboot-producer
和dubbo-springboot-consumer
。
创建一个为阿里云部署的模版文件,docker-compose-acs.yml,内容和docker-compose.yml类似。
version: "2"
services:zookeeper:image: 'registry.aliyuncs.com/acs-sample/zookeeper:3.4.8'hostname: zookeeperproducer:image: 'registry.cn-hangzhou.aliyuncs.com/${rname}/dubbo-springboot-producer:latest'environment:- ZOOKEEPER_SERVER=zookeeperconsumer:image: 'registry.cn-hangzhou.aliyuncs.com/${rname}/dubbo-springboot-consumer:latest'environment:- ZOOKEEPER_SERVER=zookeeper- SERVER_PORT=8899labels:aliyun.routing.port_8899: http://ds-consumer
这个部署文件和docker-compose.yml内容不同之处在于,所有容器到主机端口映射都去掉了,为了能访问consumer,使用了aliyun.routing.port_8899
为consumer指定一个子域名。集群部署后可用如下URL访问consumer服务。
http://ds-consumer.c67***8cd5.cn-shenzhen.alicontainer.com
登陆阿里云容器服务控制台 https://cs.console.aliyun.com,利用部署模版创建一个新应用,部署模版的内容就是上面docker-compose-acs.yml内容,提示rname
时输入你的容器仓库用户名,很快应用部署就会成功。
在控制台中进入consumer服务页面,找到访问端点:
点击地址,可以在浏览器中看到输出:
至此,我们成功地在云上运行了Dubbo应用。
本文中的compose模版部署为v2版本,如果大家想尝试利用v3版本部署,可以访问github
讨论
在网上有讨论容器化的Dubbo应用发送的IP地址不对,经实测在Docker 1.12版本下没有这个问题,部署到阿里云容器服务上也正常。本文的示例代码在github上,大家可以参考。
小节
本文通过Spring Boot构建了一个最小的Dubbo应用,容器化后成功部署到阿里云容器服务上。
在Docker中运行Dubbo应用相关推荐
- docker保护python源码_Tensorflow在Docker中运行和源码编译
本文分享在在Docker中运行Tensorflow和进行源码编译的方法和步骤,包括:编译.构建docker镜像.创建和运行Docker容器.部署完的容器可以通过Jupyter Notebook进行访问 ...
- ASP.NET Core 网站在Docker中运行
Docker作为新一代的虚拟化方式,未来肯定会得到广泛的应用,传统虚拟机的部署方式要保证开发环境.测试环境.UAT环境.生产环境的依赖一致性,需要大量的运维人力,使用Docker我们可以实现一次部署, ...
- 在docker中运行ASP.NET Core Web API应用程序
本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过程中,也会对docker的使用进行一些简单的描述.对于.NET Cor ...
- 在Docker中运行ASP.NET Web API解决方案
目录 介绍 先决条件 如何容器化现有项目 添加docker-compose项目 带有docker-compose的容器化解决方案 添加环境变量 后端 前端 不使用Visual Studio运行您的应用 ...
- 如何在docker中运行MySQL实例(转载)
如何在docker中运行MySQL实例 转自:https://blog.csdn.net/siying8419/article/details/79670246 通常初学者学习docker时,不太清楚 ...
- zkeacms mysql_在Docker中运行纸壳CMS并配置使用MySql
纸壳CMS是基于ASP .Net Core开发的可视化内容管理系统,可以跨平台部署,可以在容器中运行.接下来看看如何在docker中运行纸壳CMS. 方式一 直接运行以下命令即可在docker中运行纸 ...
- k3d入门指南:在Docker中运行K3s
在本文中,我们将简单了解k3d,这是一款可让您在安装了Docker的任何地方运行一次性Kubernetes集群的工具,此外在本文中我们还将探讨在使用k3d中可能会出现的一切问题. 什么是k3d? k3 ...
- 在Docker中运行EOS(MAC版)
在Docker中运行EOS(MAC版) 在Docker中也可以简单快速的构建EOS.IO.笔者在Mac平台下参考官方文档躺了一次河.记录如下: 安装依赖 Docker 版本 17.05或者更高 tes ...
- docker中运行bash: mongo: command not found报错问题处理(直接使用mongosh)
问题描述: docker中运行bash: mongo: command not found报错问题处理 原因: mongo命令在mongodb 6.0已经不适用了 解决方案: 直接使用mongosh
最新文章
- VTK:图片之ImageMask
- java获取mysql执行计划_好程序员Java学习路线之MySQL的执行计划
- ubuntu 启动图形界面命令_Windows 10 远程连接 Ubuntu 18.04 Server图形界面
- SpringMVC+uploadify文件上传
- 【Axure组件库】Axure移动端小程序组件库 移动端高交互元件库
- C++ 隐藏窗口在任务栏的显示
- 计算机二级方案管理器,计算机二级考试真题-Word-学生成绩管理系统需求分析
- java开发环境实验总结_20155229 实验一《Java开发环境的熟悉》实验报告
- 戴尔服务器怎么u盘安装win7系统教程,戴尔电脑怎么用u盘装win7系统教程
- python计算现场得分_如何使用Python(scikitlearn)计算factorananalysis得分?
- ps换背景操作,巨简单
- 计算机网络二分法划分网络,三种经典复杂网络社区结构划分算法研究_GN算法
- [Angular实战网易云]——15、歌词渲染
- 微信小程序 image图片组件实现宽度固定 高度自适应
- Linux下的FireBird安装
- Jython-在JAVA调用Python脚本使用方法详解+示例代码
- 笔记:处理token过期
- 使用canvas画迁徙线并加上动态效果与小飞机图标
- python粘贴代码到word_写论文必备,在线代码高亮工具,无缝粘贴到 Word
- 华为设备NAC配置命令
热门文章
- WCF扩展:行为扩展Behavior Extension一
- JavaScriptSerializer进行JSON序列化,得到字符串
- 用SqlDataAdapter.Update(DataSet Ds)更新数据库
- 哈希表(散列查找)(c/c++)
- ArcGIS 复制要素
- appium+python自动化40-adb offline(5037端口被占)
- 在 Spring中 创建 JavaBean
- 《云计算:原理与范式》一3.9 SaaS集成服务
- 德国政府发布新网络安全战略
- (转)创建Windows服务(Windows Services)N种方式总结