四时宝库

程序员的知识宝库

docker-compose 实现最简单的微服务架构

什么是微服务

顾名思义:指的是很小的独立服务。服务是什么呢?实现一个简单的业务逻辑既是一个服务。所以我们说微服务是指一个简单的业务逻辑用多个独立的小型服务实现。既然了解了什么是微服务,那我们今天就用docker按照微服务的设置思路来实现一个简单的业务逻辑。

业务逻辑

简单说:需要一个web展示页面,访问这个web可以输入名字,根据输入的名字动态生成一个简易的像素图标作为这个名字的头像。

复杂说:通过python Flask创建一个网页,要有输入框和提交按钮,通过Flask的response返回头像;当我们输入名字之后交于dnmonster容器处理,这个容器返回一个头像给Flask 网页;使用Redis缓存技术,当输入的名字已经在缓存中不再重新请求dnmonster容器,直接返回头像。

业务实现

编写python文件 identidock.py

mkdir -p identidock/app
cd identidock/app
vim identidock/app/identidock.py
#! coding=utf-8
# 导入要用到的模块
from flask import Flask, Response, request
import requests
import hashlib
import redis
?
app = Flask(__name__)
# 建立redis缓存,连接到redis
cache = redis.StrictRedis(host='redis', port=6379, db=0)
# 定义salt值,salted = salt + name
salt = "UNIQUE_SALT"
default_name = 'CGLS Blog'
# 设置route支持get和post两种请求
@app.route('/', methods=['GET', 'POST'])
def mainpage():
 name = default_name
 # 提交姓名
 if request.method == 'POST':
 name = request.form['name']
 salted_name = salt + name
 # 对姓名进行SHA256加密运算
 name_hash = hashlib.sha256(salted_name.encode()).hexdigest()
 header = '<html><head><title>Identidock</title></head><body>'
 body = '''<form method="POST">
 Hello <input type="text" name="name" value="{0}">
 <input type="submit" value="submit">
 </form>
 <p>You look like a:
 <img src="/monster/{1}"/>
 '''.format(name, name_hash)
 footer = '</body></html>'
 # 返回web页面
 return header + body + footer
?
@app.route('/monster/<name>')
def get_identicon(name):
 # 检查姓名是否在缓存中
 image = cache.get(name)
 if image is None:
 print ("Cache miss", flush=True)
 # 获取相应的头像
 r = requests.get('http://dnmonster:8080/monster/' + name + '?size=80')
 image = r.content
 # 将姓名和头像一起写到缓存中
 cache.set(name, image)
 # 返回头像
 return Response(image, mimetype='image/png')
?
if __name__ == '__main__':
 app.run(debug=True, host='0.0.0.0')

编写cmd.sh文件

vim identidock/cmd.sh
#!/bin/bash
set -e
?
if [ "$ENV" = 'DEV' ]; then
 echo "Running Development Server"
 exec python "identidock.py"
else
 echo "Running Production Server"
 exec uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191

编写Dockerfile

vim Dockerfile
FROM python:3.4
?
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI requests==2.5.1 redis==2.10.3
WORKDIR /app
COPY app /app
COPY cmd.sh /
RUN chmod +x /cmd.sh
EXPOSE 9090 9191
USER uwsgi
?
CMD ["/cmd.sh"] 

编写docker-compose.yml

vim docker-compose.yml
identidock:
 build: .
 ports:
 - "5000:5000"
 environment:
 ENV: DEV 
 volumes:
 - ./app:/app
 links:
 - dnmonster
 - redis
?
dnmonster:
 image: amouat/dnmonster:1.0
?
redis:
 image: redis:3.0

简单说一下上面几个文件之间的关系

docker-compose.yml自动化管理Dockerfile创建docker identidock镜像并控制运行identidock容器,dnmonster容器,redis容器。Dockerfile是为了创建identidock镜像,它用到了cmd.sh脚本,并且使用了identidock.py文件。cmd.sh文件是判断环境是调试环境还是生产环境,根据环境不同启用不同的命令。identidock.py文件是为了实现web页面,并使用redis容器的缓存存储功能和dnmonster容器的返回头像功能。

接下来就是生成容器集群了:

# 创建需要的identidock镜像
cd identidock
docker-compose build
# 生成并启动容器集群
docker-compose up -d
# 查看自己的集群,如果你开启了防火墙记得打开5000端口
docker-compose ps
浏览器访问http://<localhost_ip>:5000

总结

我们创建的业务逻辑应用,使用到了三个微型服务,分别是web服务提供web页面;nodejs服务提供返回头像;redis服务提供缓存存储。通过docker自动化工具docker-compose进行管理,根据实际情况我们可以对这几个服务进行动态扩展。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接