一、创建一个简单的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. (转 )【Android那些高逼格的写法】InvocationHandler与代理模式

    转自这个公众号: 今天会聊一下InvocationHandler.说到InvocationHandler不得不提到的就是代理模式,什么是代理模式,举个例子,你玩游戏,花钱请个代练,代练其实是登录你的账 ...

  2. Servlet 点击计数器

    网页点击计数器 很多时候,您可能有兴趣知道网站的某个特定页面上的总点击量.使用 Servlet 来计算这些点击量是非常简单的,因为一个 Servlet 的生命周期是由它运行所在的容器控制的. 以下是实 ...

  3. Spring MVC单选按钮

    以下示例显示如何在使用Spring Web MVC框架的表单中使用单选按钮(RadioButton).首先使用Eclipse IDE来创建一个WEB工程,并按照以下步骤使用Spring Web Fra ...

  4. Eclipse 浏览(Navigate)菜单

    浏览 Eclipse 工作空间 浏览(Navigate)菜单提供了多个菜单可以让你快速定位到指定资源. 上图中 Open Type, Open Type in Hierarchy 和 Open Res ...

  5. python 类成员的修饰符

    类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式: 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能方法 私有成员和公有成员的定义不同:私有成员命名时,前两个字 ...

  6. linux下jmeter使用帮助

    1.linux下jmeter使用方法 例:jmeter -n -t test1.jmx -l logfile1.jtl -H 192.168.1.1 -P 8080 -h 帮助 -> 打印出有用 ...

  7. 《从零开始学Swift》学习笔记(Day 38)——构造函数与存储属性初始化

    原创文章,欢迎转载.转载请注明:关东升的博客 构造函数的主要作用是初始化实例,其中包括:初始化存储属性和其它的初始化.在Rectangle类或结构体中,如果在构造函数中初始化存储属性width和hei ...

  8. LIS(模板)

    记录一下,O(nlgn)的算法求LIS //HHH #include <iostream> #include <stdio.h> #include <string.h&g ...

  9. linux /etc/security/limits.conf的相关说明

    暂时粘贴他人的地址,后续会整理后放出. 原文地址:http://blog.csdn.net/taijianyu/article/details/5976319

  10. python列表和元组相互转换

    # 将列表转化为元组 lst=[11,22,33] t=tuple(lst) print(t,type(t)) # 打印结果:(11, 22, 33) <class 'tuple'> tu ...