一、创建一个简单的Web应用

1.identicon

基于某个值而自动产生的图像,这个值是IP地址或用户名的散列值。

用途:

通过计算用户名或IP地址的散列值,在网站上提供用于识别用户的图像,以及自动生成网站的favicon。

2.创建一个基本网页

[root@bogon app]# cat identidock.py
from flask import Flask
app = Flask(__name__) default_name = 'Xiaoda' @app.route('/')
def mainpage():
name = default_name header = '<html><head><title>Identidock</title></head><body>'
body = '''<form method="POST">
Hello <input type="text" name="name" value="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>' return header + body + footer if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0') [root@bogon identidock]# cat docker-compose.yml
identidock:
build: .
ports:
- "6900:6900"
environment:
ENV: DEV
volumes:
- ./app:/app [root@bogon identidock]# docker-compose up -d
Building identidock
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Using cache
---> bb39db2742b4
Step 3/5 : WORKDIR /app
---> Using cache
---> 7159f825056f
Step 4/5 : COPY app /app
---> b13830295303
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Running in 8d69046d66d7
---> 92852ec52596
Removing intermediate container 8d69046d66d7
Successfully built 92852ec52596
Successfully tagged identidock_identidock:latest
WARNING: Image for service identidock was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating identidock_identidock_1 ...
Creating identidock_identidock_1 ... done

2.利用现有镜像

[root@bogon app]# cat identidock.py
from flask import Flask,Response
import requests app = Flask(__name__)
default_name = 'Xiaoda' @app.route('/')
def mainpage():
name = default_name header = '<html><head><title>Identidock</title></head><body>'
body = '''<form method="POST">
Hello <input type="text" name="name" value="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>' return header + body + footer
@app.route('/monster/<name>')
def get_identicon(name):
r = requests.get('http://dnmonster:8080/monster/' + name + '?size=80')
image = r.content return Respinse(image, mimetype='image/png') if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0') [root@bogon identidock]# cat Dockerfile.1031
FROM python:3.4 RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI==2.0.8 requests==2.5.1
WORKDIR /app
COPY app /app EXPOSE 9090 9191
USER uwsgi CMD ["/cmd.sh"] [root@bogon identidock]# docker build -t identidock .
Sending build context to Docker daemon 7.168kB
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Using cache
---> bb39db2742b4
Step 3/5 : WORKDIR /app
---> Using cache
---> 7159f825056f
Step 4/5 : COPY app /app
---> 3080bcfb4b16
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Running in ea63b5069cc2
---> 3966bef511e5
Removing intermediate container ea63b5069cc2
Successfully built 3966bef511e5
Successfully tagged identidock:latest [root@bogon identidock]# docker run -d --name dnmonster amouat/dnmonster:1.0
Unable to find image 'amouat/dnmonster:1.0' locally
1.0: Pulling from amouat/dnmonster
a3ed95caeb02: Pull complete
453d13af6c96: Pull complete
Digest: sha256:e9e991ffa0d05583af0ed0541d03c519d37762750c462bd86b3546f600e11231
Status: Downloaded newer image for amouat/dnmonster:1.0
4136951e5602ccb1939a0d47552b0fc9f2bf217baef640837e152cb09e5fdc11 [root@bogon identidock]# docker run -d -p 6800:6800 -e "ENV=DEV" --link dnmonster:dnmonster identidock
dd27f8941770b13b18a3b48157f440f91081a73655bc7ca25a11dcf1c244ddcb

改进版:

[root@bogon identidock]# cat docker-compose.yml
identidock:
build: .
ports:
- "6900:6900"
environment:
ENV: DEV
volumes:
- ./app:/app
links:
- dnmonster dnmonster:
image: amouat/dnmonster:1.0 [root@bogon identidock]# docker rm $(docker stop $(docker ps -q))
dd27f8941770
4136951e5602
f0a6553a9c33 [root@bogon identidock]# docker-compose build
dnmonster uses an image, skipping
Building identidock
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Using cache
---> bb39db2742b4
Step 3/5 : WORKDIR /app
---> Using cache
---> 7159f825056f
Step 4/5 : COPY app /app
---> 4258a3f27a07
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Running in 7898c0f79b37
---> 6eda3dd73c7a
Removing intermediate container 7898c0f79b37
Successfully built 6eda3dd73c7a
Successfully tagged identidock_identidock:latest [root@bogon identidock]# docker-compose up -d
Creating identidock_dnmonster_1 ...
Creating identidock_dnmonster_1 ... done
Creating identidock_identidock_1 ...
Creating identidock_identidock_1 ... done [root@bogon app]# cat identidock.py
from flask import Flask,Response
import requests
import hashlib app = Flask(__name__)
salt = "UNIQUE_SALT"
default_name = 'Xiaoda' @app.route('/')
def mainpage():
name = default_name if request.method == 'POST':
name = request.form['name'] salted_name = salt + name
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="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>' return header + body + footer @app.route('/monster/<name>')
def get_identicon(name):
r = requests.get('http://dnmonster:8080/monster/' + name + '?size=80')
image = r.content return Respinse(image, mimetype='image/png') if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

二、实现缓存功能

1.在一个容器中运行多个进程

使用进程管理器supervisord,负责进程的启动和监视。

[root@bogon app]# cat identidock.py
from flask import Flask,Response
import requests
import hashlib
import redis app = Flask(__name__)
cache = redis.StrictRedis(host='redis',port=6379,db=0)
salt = "UNIQUE_SALT"
default_name = 'Xiaoda' @app.route('/',methods=['GET','POST'])
def mainpage():
name = default_name if request.method == 'POST':
name = request.form['name'] salted_name = salt + name
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="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>' 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 Respinse(image, mimetype='image/png') if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
[root@bogon identidock]# cat Dockerfile.1031
FROM python:3.4 RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI==2.0.8 requests==2.5.1 redis==2.10.6
WORKDIR /app
COPY app /app
COPY cmd.sh / EXPOSE 9090 9191
USER uwsgi CMD ["/cmd.sh"]
[root@bogon identidock]# cat docker-compose.yml
identidock:
build: .
ports:
- "7000:7000"
environment:
ENV: DEV
volumes:
- ./app:/app
links:
- dnmonster
- redis dnmonster:
image: amouat/dnmonster:1.0 redis:
image: redis:3.0 [root@bogon identidock]# docker-compose build
dnmonster uses an image, skipping
redis uses an image, skipping
Building identidock
Step 1/9 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/9 : RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
---> Using cache
---> 1aa7c9d755eb
Step 3/9 : RUN pip install Flask==0.10.1 uWSGI==2.0.8 requests==2.5.1 redis==2.10.6
---> Running in 107013f2d391
Collecting Flask==0.10.1
Downloading Flask-0.10.1.tar.gz (544kB)
Collecting uWSGI==2.0.8
Downloading uwsgi-2.0.8.tar.gz (775kB)
Collecting requests==2.5.1
Downloading requests-2.5.1-py2.py3-none-any.whl (464kB)
Collecting redis==2.10.6
Downloading redis-2.10.6-py2.py3-none-any.whl (64kB)
Collecting Werkzeug>=0.7 (from Flask==0.10.1)
Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
Collecting Jinja2>=2.4 (from Flask==0.10.1)
Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
Collecting itsdangerous>=0.21 (from Flask==0.10.1)
Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask==0.10.1)
Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: Flask, uWSGI, itsdangerous, MarkupSafe
Running setup.py bdist_wheel for Flask: started
Running setup.py bdist_wheel for Flask: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/b6/09/65/5fcf16f74f334a215447c26769e291c41883862fe0dc7c1430
Running setup.py bdist_wheel for uWSGI: started
Running setup.py bdist_wheel for uWSGI: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/04/43/f1/b6308e3b9ea71a31b9e5b69b6fe50bea89e852688bf46e8b92
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built Flask uWSGI itsdangerous MarkupSafe
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, Flask, uWSGI, requests, redis
Successfully installed Flask-0.10.1 Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 itsdangerous-0.24 redis-2.10.6 requests-2.5.1 uWSGI-2.0.8
---> 25710c7b3813
Removing intermediate container 107013f2d391
Step 4/9 : WORKDIR /app
---> 9178ae566c42
Removing intermediate container 541c592bf996
Step 5/9 : COPY app /app
---> 756498c4229c
Step 6/9 : COPY cmd.sh /
---> 67416d7b3c6b
Step 7/9 : EXPOSE 9090 9191
---> Running in e3fb71c7cb6a
---> e9c0c03315ad
Removing intermediate container e3fb71c7cb6a
Step 8/9 : USER uwsgi
---> Running in f952ebf8f50b
---> 732e703b3373
Removing intermediate container f952ebf8f50b
Step 9/9 : CMD /cmd.sh
---> Running in 9943687a5efa
---> 94f20e22970d
Removing intermediate container 9943687a5efa
Successfully built 94f20e22970d
Successfully tagged identidock_identidock:latest [root@bogon identidock]# docker-compose up -d
Pulling redis (redis:3.0)...
3.0: Pulling from library/redis
f5cc0ee7a6f6: Pull complete
5fc25ed18e87: Pull complete
e025bc8872f6: Pull complete
77c68b51b836: Pull complete
7c403ece3755: Pull complete
0a653bd338f4: Pull complete
31531fd948c6: Pull complete
Digest: sha256:730b765df9fe96af414da64a2b67f3a5f70b8fd13a31e5096fee4807ed802e20
Status: Downloaded newer image for redis:3.0
Starting identidock_dnmonster_1 ...
Starting identidock_dnmonster_1
Creating identidock_redis_1 ...
Creating identidock_redis_1 ... done
Recreating identidock_identidock_1 ...
Recreating identidock_identidock_1 ... done

三、微服务

微服务:由多个独立的小服务组成;

单一服务架构:该系统包含在一个单独的大型的服务之中(dnmonster、redis和identidock使用同一种编程语言实现)。

优点:

  • 适合横向扩展到多态机器
  • 轻松快速地被其他效能更高且功能相同的服务替代
  • 若发生意外,可只对部分微服务进行回滚
  • 不同微服务可以用不同的语言实现,使开发者更好适用任务语言

缺点:

  • 分布式组件所导致的额外开销
  • 通信必须通过网络,而不是库的调用
  • 服务编排和服务发现

Docker容器技术-创建一个简单的Web应用的更多相关文章

  1. 利用HTML5与jQuery技术创建一个简单的自动表单完成

    来源:GBin1.com 在线演示   在线下载 谷歌快速搜索自带大量自动完成插件——库中甚至还有一个附带的jQuery UI共享选项.然而今天我要寻找一个替代的解决方案.由DevBridge开发的j ...

  2. IntelliJ IDEA 15 部署Tomcat及创建一个简单的Web工程

    一.部署Tomcat 二.创建一个简单的Web工程 2.1创建一个新工程 创建一个新工程 设置JDK及选择Web Application (创建的是Web工程) 点击Next,选择工作空间,起个工程名 ...

  3. Symfony2之创建一个简单的web应用

    Symfony2——创建bundle       bundle就像插件或者一个功能齐全的应用,我们在应用层上开发的应用的所有代码,包括:PHP文件.配置文件.图片.css文件.js文件等都会包含在bu ...

  4. 使用 CodeIgniter 创建一个简单的 Web 站点

    原文:使用 CodeIgniter 创建一个简单的 Web 站点 参考源自: http://www.ibm.com/developerworks/cn/web/wa-codeigniter/index ...

  5. SharePoint 创建一个简单的Web Part 部分

    SharePoint 创建一个简单的Web Part 部分 标准Web零件有时会很强大,运行多个功能的能力. 本文介绍了如何使用Visual Studio 创建一个简单的Web部分. 1. 打开VS, ...

  6. 用 Eclipse 创建一个简单的web项目

    Eclipse neon 汉化版 ; 1;右击新建 -->  选择 动态Web项目 2:  填写 项目名 项目位置 ; 选择 Dynamic web module version 和 tomca ...

  7. django创建一个简单的web站点

    一.新建project 使用Pycharm,File->New Project…,选择Django,给project命名 (project不能用test命名)   新建的project目录如下: ...

  8. node创建一个简单的web服务

    本文将如何用node创建一个简单的web服务,过程也很简单呢~ 开始之前要先安装node.js 1.创建一个最简单的服务 // server.js const http = require('http ...

  9. Symfony2之创建一个简单的web应用 Symfony2——创建bundle

    bundle就像插件或者一个功能齐全的应用,我们在应用层上开发的应用的所有代码,包括:PHP文件.配置文件.图片.css文件.js文件等都会包含在bunde系统中.          可以通过两种方法 ...

随机推荐

  1. 如何在shell中处理异常(转)

    似乎好像大概有句话是这么说得,好程序与坏程序之间的区别就在于它的鲁棒性,也就是在异常情况下该程序是否还是在可hold住状态,能否不死,不崩溃,或者不做出一些超出预期的事情.那要做好这些,自然而然就要学 ...

  2. Python数据驱动ddt

    import ddtimport unittest """ddt模块包含了一个类的装饰器ddt和两个方法的装饰器: data:包含多个你想要传给测试用例的参数: file ...

  3. 【BZOJ2770】YY的Treap 结论+线段树

    [BZOJ2770]YY的Treap Description 志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap.友爱教教父SY如砍瓜切菜般教会了Y ...

  4. jQuery之获取select选中的值

    本来以为jQuery("#select1").val();是取得选中的值, 那么jQuery("#select1").text();就是取得的文本. 这是不正确 ...

  5. 记一次服务器inodes数报警的事件

    # df -i 执行以上命令,发现/上的 inodes 占用率为81%,于是开始处理. 首先找出哪个目录底下文件数最多: # cd / # for i in $(ls);do echo ${i} &a ...

  6. 64位matlab mex64位编译器解决方案

    安装libsvm的时候用到了mex -setup,有的会报 Could not find the 64-bit compiler. This may indicate that the "X ...

  7. hctf2016 fheap学习(FreeBuf发表的官方解法)

    目录 如何在二次释放前修改函数指针 修改函数指针流程 如何获得进程的加载基址 puts函数的调用 如何获取system函数地址 说一下用DlyELF函数 如何调用system函数 ROP需要的栈布局 ...

  8. 问题:Unable to find a 'userdata.img' file for ABI armeabi to copy into the AVD folder.

    创建AVD时,发现创建不成功,报错“Unable to find a 'userdata.img' file for ABIarmeabi to copy into the AVD folder.” ...

  9. Java里的CompareAndSet(CAS)

    ;            if (compareAndSet(current, next))                return next;        }    } 首先可以看到他是通过一 ...

  10. 接口测试工具 — jmeter(基本使用)

    1.打开jemeter(bin目录下jemter.bat) 2.基本操作