关于微服务的资料很多,只是用谷歌搜索就可以了 ! 几年前,我在比利时的Devoxx上发表了有关将单片重构为微服务的演讲,它得到了很好的评价:
该博客将展示Docker如何简化微服务的创建和关闭。
该博客中使用的所有代码都在github.com/arun-gupta/couchbase-javaee上 。
使用撰写的微服务定义
Docker 1.13引入了Docker Compose v3 。 语法上的更改很小,但主要区别是添加了deploy属性。 此属性允许为容器指定副本,滚动更新和重新启动策略。
我们的微服务将使用预先部署的Java EE应用程序启动WldFly应用程序服务器。 该应用程序将与Couchbase数据库对话以获取CRUD应用程序数据。
这是Compose定义:
version: '3'
services:
web:
image: arungupta/couchbase-javaee:travel
environment:
- COUCHBASE_URI=db
ports:
- 8080:8080
- 9990:9990
depends_on:
- db
db:
image: arungupta/couchbase:travel
ports:
- 8091:8091
- 8092:8092
- 8093:8093
- 11210:11210
在此撰写文件中:
- 此Compose中的两个服务由名称
db
和web
属性定义 - 使用
image
属性定义的每个服务的图像名称 -
arungupta/couchbase:travel
图像将启动Couchbase服务器,使用Couchbase REST API对其进行配置,并使用〜32k JSON文档加载travel-sample
存储桶。 -
arungupta/couchbase-javaee:travel
映像启动WildFly并部署从https://github.com/arun-gupta/couchbase-javaee构建的应用程序WAR文件。 如果要构建自己的映像,请克隆该项目。 -
envrionment
属性定义了WildFly中部署的应用程序可访问的环境变量。COUCHBASE_URI
引用数据库服务。 在https://github.com/arun-gupta/couchbase-javaee/blob/master/src/main/java/org/couchbase/sample/javaee/Database.java所示的应用程序代码中使用了此代码。 - 端口转发是使用
ports
属性实现的 -
Compose定义文件中的
depends_on
属性可确保容器启动顺序。 但是应用程序级别的启动需要通过容器内运行的应用程序来确保。 在我们的例子中,WildFly的启动速度非常快,但是要花几秒钟才能启动数据库。 这意味着WildFly中部署的Java EE应用程序无法与数据库进行通信。 这概述了构建微服务应用程序时的最佳实践:您必须进行防御性编码,并在应用程序初始化中确保依赖的微服务已启动,而无需假定启动顺序。 这显示在https://github.com/arun-gupta/couchbase-javaee/blob/master/src/main/java/org/couchbase/sample/javaee/Database.java的数据库初始化代码中。 它执行以下检查:- 铲斗存在
- Couchbase的查询服务已启动并正在运行
- 样品桶已满载
可以在单个主机上使用docker-compose up -d
命令启动该应用程序。 或使用docker stack deploy
命令以群集模式运行的Docker引擎集群。
设置Docker Swarm模式
使用以下命令初始化Swarm模式:
docker swarm init
这将启动“群管理器”。 默认情况下,管理者节点也是工作者,但可以配置为仅管理者。
使用命令docker info
命令查找有关此单节点集群的一些信息:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 17
Server Version: 1.13.0
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Swarm: active
NodeID: 92mydh0e09ba5hx3wtmcmvktz
Is Manager: true
ClusterID: v68ikyaff7rdxpaw1j0c9i60s
Managers: 1
Nodes: 1
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 3
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Node Address: 192.168.65.2
Manager Addresses:
192.168.65.2:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 03e5862ec0d8d3b3f750e19fca3ee367e13c090e
runc version: 2f7393a47307a16f8cee44a37b262e8b81021e3e
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 4.9.5-moby
Operating System: Alpine Linux v3.5
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 1.952 GiB
Name: moby
ID: SGCM:KDRD:G3M7:PZHN:J4RL:VFFR:G2SR:EKD5:JV4J:RL3X:LF7T:XF6V
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): true
File Descriptors: 31
Goroutines: 124
System Time: 2017-01-27T08:25:58.032295342Z
EventsListeners: 1
No Proxy: *.local, 169.254/16
Username: arungupta
Registry: https://index.docker.io/v1/
Experimental: true
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
该集群有1个节点,即节点。
或者,可以使用Docker for AWS轻松设置多主机集群。
部署微服务
可以通过以下方式启动微服务:
docker stack deploy --compose-file=docker-compose.yml webapp
显示输出:
Creating network webapp_default
Creating service webapp_web
Creating service webapp_db
WildFly和Couchbase服务在此节点上启动。 每个服务都有一个容器。 如果在多个节点上启用了Swarm模式,则容器将分布在多个节点上。
创建一个新的覆盖网络。 这允许不同主机上的多个容器相互通信。
使用docker docker service ls
验证WildFly和Couchbase服务是否正在运行:
ID NAME MODE REPLICAS IMAGE
a9pkiziw3vgw webapp_db replicated 1/1 arungupta/couchbase:travel
hr5s6ue54kwj webapp_web replicated 1/1 arungupta/couchbase-javaee:travel
可以使用docker service logs -f webapp_web
查看该服务的docker service logs -f webapp_web
:
webapp_web.1.wby0b04t7bap@moby | =========================================================================
webapp_web.1.wby0b04t7bap@moby |
webapp_web.1.wby0b04t7bap@moby | JBoss Bootstrap Environment
webapp_web.1.wby0b04t7bap@moby |
webapp_web.1.wby0b04t7bap@moby | JBOSS_HOME: /opt/jboss/wildfly
webapp_web.1.wby0b04t7bap@moby |
webapp_web.1.wby0b04t7bap@moby | JAVA: /usr/lib/jvm/java/bin/java
webapp_web.1.wby0b04t7bap@moby |
webapp_web.1.wby0b04t7bap@moby | JAVA_OPTS: -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true
webapp_web.1.wby0b04t7bap@moby |
webapp_web.1.wby0b04t7bap@moby | =========================================================================
. . .
webapp_web.1.wby0b04t7bap@moby | 23:14:15,811 INFO [org.jboss.as.server] (ServerService Thread Pool -- 34) WFLYSRV0010: Deployed "airlines.war" (runtime-name : "airlines.war")
webapp_web.1.wby0b04t7bap@moby | 23:14:16,076 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
webapp_web.1.wby0b04t7bap@moby | 23:14:16,077 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
webapp_web.1.wby0b04t7bap@moby | 23:14:16,077 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.1.0.Final (WildFly Core 2.2.0.Final) started in 98623ms - Started 443 of 691 services (404 services are lazy, passive or on-demand)
存取微服务
从微服务获取10家航空公司:
curl -v http://localhost:8080/airlines/resources/airline
结果显示为:
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /airlines/resources/airline HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< X-Powered-By: Undertow/1
< Server: WildFly/10
< Content-Type: application/octet-stream
< Content-Length: 1402
< Date: Fri, 03 Feb 2017 17:02:45 GMT
<
* Connection #0 to host localhost left intact
[{"travel-sample":{"country":"United States","iata":"Q5","callsign":"MILE-AIR","name":"40-Mile Air","icao":"MLA","id":10,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"TQ","callsign":"TXW","name":"Texas Wings","icao":"TXW","id":10123,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"A1","callsign":"atifly","name":"Atifly","icao":"A1F","id":10226,"type":"airline"}}, {"travel-sample":{"country":"United Kingdom","iata":null,"callsign":null,"name":"Jc royal.britannica","icao":"JRB","id":10642,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"ZQ","callsign":"LOCAIR","name":"Locair","icao":"LOC","id":10748,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"K5","callsign":"SASQUATCH","name":"SeaPort Airlines","icao":"SQH","id":10765,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"KO","callsign":"ACE AIR","name":"Alaska Central Express","icao":"AER","id":109,"type":"airline"}}, {"travel-sample":{"country":"United Kingdom","iata":"5W","callsign":"FLYSTAR","name":"Astraeus","icao":"AEU","id":112,"type":"airline"}}, {"travel-sample":{"country":"France","iata":"UU","callsign":"REUNION","name":"Air Austral","icao":"REU","id":1191,"type":"airline"}}, {"travel-sample":{"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlinair","icao":"RLA","id":1203,"type":"airline"}}]
Docker for Java Developers研讨会是一个自定进度的动手实验,它使您可以轻松地开始使用Docker。
获取单个资源:
curl -v http://localhost:8080/airlines/resources/airline/137
创建一个新资源:
curl -v -H "Content-Type: application/json" -X POST -d '{"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlinair","icao":"RLA","type":"airline"}' http://localhost:8080/airlines/resources/airline
更新资源:
curl -v -H "Content-Type: application/json" -X PUT -d '{"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlin Air","icao":"RLA","type":"airline","id": "19810"}' http://localhost:8080/airlines/resources/airline/19810
删除资源:
curl -v -X DELETE http://localhost:8080/airlines/resources/airline/19810
每个命令的详细输出在github.com/arun-gupta/couchbase-javaee上 。
删除微服务
可以使用命令docker stack rm webapp
删除微服务:
Removing service webapp_web
Removing service webapp_db
Removing network webapp_default
想要开始使用Couchbase吗? 查看Couchbase入门套件 。
想更多地了解如何在容器中运行Couchbase?