zoukankan      html  css  js  c++  java
  • Docker容器技术-创建一个简单的Web应用

    一、创建一个简单的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使用同一种编程语言实现)。

    优点:

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

    缺点:

    • 分布式组件所导致的额外开销
    • 通信必须通过网络,而不是库的调用
    • 服务编排和服务发现
  • 相关阅读:
    C#执行sql文件
    "C:Program FilesInternet Exploreriexplore.exe" -extoff 无加载项启动IE 浏览器打开时全屏模式
    sql server备份与还原 sql语句
    触摸屏\串口服务器\串口
    USB串行端口
    选取所有表单元素
    C# Bitmap类型与Byte[]类型相互转化
    本文介绍C# BitmapData
    C#多线程学习(六) 互斥对象
    C# List 复制克隆副本
  • 原文地址:https://www.cnblogs.com/tongxiaoda/p/7749823.html
Copyright © 2011-2022 走看看