美文网首页
搭建一个简单的分布式系统(1)

搭建一个简单的分布式系统(1)

作者: 知识分子中的文盲 | 来源:发表于2016-06-12 23:43 被阅读3395次

    这个系统的功能非常简单,只是在页面上显示一些文本(Hello,XXX)。搭建这个系统的初衷并不是为了完成这个功能,而是将码农周刊中使用到的一些技术都自己测试一遍。一方面了解下现在互联网公司所使用的一些技术,另一方面为以后工具选型积累一些知识,提供一些参考。
    搭建思路也是按照开发思路,先出来一个雏形,然后慢慢丰满羽翼。
    其中有些技术和码农周刊中使用的不一样,主要考虑到本人的熟悉程度和工作需要。比如周刊的web开发框架是pyramid,WSGI协议实现使用gunicorn,我这里分别使用的是flask和uWSGI。

    网页显示Hello Simon

    • 安装virtualenv隔离环境
    $ sudo pip install virtualenv
    $ virtualenv --no-site-packages aries # 不使用系统的依赖
    hqi@hqi-VirtualBox:~/buildout$ virtualenv --no-site-packages aries
    New python executable in /home/hqi/buildout/aries/bin/python
    Installing setuptools, pip, wheel...done.
    hqi@hqi-VirtualBox:~/buildout/aries$ source ./bin/activate
    (aries) hqi@hqi-VirtualBox:~/buildout/aries$
    

    使用virtualenv沙盒创建一个虚拟环境。

    • 安装web开发框架flask
    pip install flask
    
    • 网页显示
    (aries) hqi@hqi-VirtualBox:~/buildout/aries$ mkdir app
    

    新建三个文件,app/init.py, app/views.py和run.py
    其中init.py创建flask application实例,views.py引入视图,完成URL映射,run.py监听请求

    init.py文件内容

    from flask import Flask
    app = Flask(__name__)
    from app import views 
    

    views.py内容

    from flask import Flask
    
    app = Flask(__name__)
    from app import views 
    (aries) hqi@hqi-VirtualBox:~/buildout/aries/app$ cat views.py 
    from app import app
    
    # URL映射,分别为/和/index
    @app.route('/')
    @app.route('/index')
    def welcome():
        return "Hello, Wendy & Simon!"
    

    run.py内容:

    from app import app
    app.debug = True 
    

    执行结果

    (aries) hqi@hqi-VirtualBox:~/buildout/aries$ python run.py 
     * Running on http://192.168.1.109:5000/ (Press CTRL+C to quit)
     * Restarting with stat
     * Debugger is active!
     * Debugger pin code: 214-462-276
    

    访问网页


    flask.JPG

    我们使用的是flask自带的WSGI实现工具,没有用到gunicorn或者uWSGI,后面会介绍Flask如何配合uWSGI使用。

    • 集成celery异步任务调度器
      Celery是Python开发的分布式任务调度模块,接口简单,开发容易,通过第三方消息服务传递任务。stack overflow上有讨论celery和apscheduler的选择,结论是推荐使用celery的多些。有关celery的高级应用,会专门写一篇文章道来。

    Flask 与 Celery 整合是十分简单,不需要任何插件。

    • 安装celery
    (aries) hqi@hqi-VirtualBox:~/buildout/aries$ pip install celery
    
    • 在初始化代码中添加celery部分,使用redis作为celery消息通道
    from flask import Flask
    from celery import Celery
    
    flask_app = Flask(__name__)
    celery = Celery(flask_app.name, \
                    broker='redis://localhost:6379/0')
    celery.conf.update(flask_app.config)
    
    from app import views
    
    • 添加控制层代码control.py
    from app import celery
    
    @celery.task
    def get_name(name="Simon"):
        return name
    
    • 在view.py中添加调用控制层接口
    from app import flask_app
    import control
    
    @flask_app.route('/')
    @flask_app.route('/index')
    def welcome(content='Simon'):
        return "Hello, " + content
    
    @flask_app.route('/name') 
    def print_name():
        return control.get_name("Wendy & Simon")
    
    get_name.JPG

    ============ flask 和 Celery整合介绍完毕 =================

    • 安装uWSGI
    $ pip install uWSGI
    $ uwsgi -h
    

    uwsgi -h出现帮助提示,表明安装成功

    • 配置uWSGI
    (aries) hqi@hqi-VirtualBox:~/buildout/aries/uwsgi$ vi aries_uwsgi.ini 
    
    [uwsgi]
    # uwsgi启动所使用的地址与端口
    socket = 192.168.1.109:8001
    #网站目录
    chdir = /home/hqi/buildout/aries 
    # python 启动程序
    wsgi-file = run.py
    #flask application实例名称
    callable = flask_app
    # 处理器个数和线程数
    processes = 4
    thread = 2
    #状态检测地址
    stats = 192.168.1.109:9191
    
    $ uwsgi --ini /home/hqi/buildout/aries/uwsgi/aries_uwsgi.ini --http :8002
    

    遇到的问题:

    1. unable to load configuration from uwsgi
      run.py中执行程序要放在main
    2. invalid request block size: 21573 (max 4096)...skip
      uWSGI默认协议是tcp,而浏览器访问协议是http,解决方案是直接提供http服务。
      uwsgi --ini /home/hqi/buildout/aries/uwsgi/aries_uwsgi.ini --http :8002
    3. 如果通过nginx访问uwsgi,uwsgi则可使用以下方式启动

    ref: http://www.tuicool.com/articles/2Araye

    uwsgi.JPG
    • 安装并运行Nginx
    $ sudo apt-get install nginx
    $ /etc/init.d/nginx start
    

    访问主机IP地址,会看到Nginx欢迎页面。

    由于Nginx不能直接执行托管Python应用程序,所以需要借助uWSGI

    • 配置Nginx和uWSGI
      Nginx和uWSGI通过socket文件相互通信
    • 配置Nginx
      Nginx默认的配置文件位于:
      /etc/nginx/sites-enabled/default
      我们在别的目录下新建一个配置文件
    (aries) hqi@hqi-VirtualBox:~/buildout/aries/nginx$ cat aries_nginx.conf 
    server {
        listen      316; # 80端口被占,使用别的端口号
        server_name 192.168.1.109;
        charset     utf-8;
        client_max_body_size 75M;
    
        location / {
            include uwsgi_params;
            # config uwsgi link
            # uwsgi_pass unix:/home/hqi/buildout/aries/nginx/aries_uwsgi.sock;
            uwsgi_pass 192.168.1.109:8001;
            uwsgi_param UWSGI_PYHOME /home/hqi/buildout/aries;
            uwsgi_param UWSGI_CHDIR /home/hqi/buildout;
            uwsgi_param UWSGI_SCRIPT run:flask_app;
        }
    }
    # Two ways to restart nginx
    $ sudo /etc/init.d/nginx restart
    $ sudo service nginx restart
    
    $ sudo nginx -c ~/buildout/aries/nginx/aries_nginx.conf
    nginx: [emerg] "server" directive is not allowed here in /home/hqi/buildout/aries/nginx/aries_nginx.conf:1
    

    Nginx必须指定配置主文件,再通过主文件加载*.conf配置文件。
    检测配置文件是否正确:

    $ sudo nginx -t -c /etc/nginx/nginx.conf
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    $ sudo service nginx restart
    [sudo] password for hqi: 
     * Restarting nginx nginx                                                                                         [ OK ]
    
    Nginx.JPG
    • 安装supervisor
      supervisor使用python写的进程控制系统。它会监测后台进程的运行状态,帮助你维护,如果它们不小心crash了,还会帮助你重启。
    $ sudo apt-get install supervisor
    $ echo_supervisord_conf > aries_supervisor.conf
    

    配置supervisor配置文件,其中最重要的配置项为program和group

    [program:nginx]
    command=nginx -c /home/hqi/buildout/aries/nginx/aries_nginx.conf     ; the program (relative uses PATH, can take args)
    process_name=%(program_name)s ; process_name expr (default %(program_name)s)
    numprocs=1                    ; number of processes copies to start (def 1)
    directory=/home/hqi/buildout/aries/supervisor            ; directory to cwd to before exec (def no cwd)
    umask=022                     ; umask for process (default None)
    priority=999                  ; the relative start priority (default 999)
    autostart=true                ; start at supervisord start (default: true)
    autorestart=true        ; whether/when to restart (default: unexpected)
    ;startsecs=1                   ; number of secs prog must stay running (def. 1)
    ;startretries=3                ; max # of serial start failures (default 3)
    exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
    stopsignal=INT               ; signal used to kill process (default TERM)
    ;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
    ;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
    ;killasgroup=false             ; SIGKILL the UNIX process group (def false)
    ;user=chrism                   ; setuid to this UNIX account to run the program
    ;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
    stdout_logfile=/home/hqi/buildout/aries/supervisor/log/stdout.log    ; stdout log path, NONE for none; default AUTO
    stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
    stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    stdout_events_enabled=false   ; emit events on stdout writes (default false)
    stderr_logfile=/home/hqi/buildout/aries/supervisor/log/stderr.log   ; stderr log path, NONE for none; default AUTO
    stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
    stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
    stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    stderr_events_enabled=false   ; emit events on stderr writes (default false)
    ;environment=A=1,B=2           ; process environment additions (def no adds)
    ;serverurl=AUTO                ; override serverurl computation (childutils)
    
    ##### Start supervisor server ##### 
    $ sudo supervisord -c aries_supervisor.conf
    ##### Shutdown supervisor server ##### 
    $ sudo supervisorctl shutdown
    ##### Reload configuration file ##### 
    $ sudo supervisorctl reload
    

    ===================================
    以上一个基本系统搭建完成,下面我会介绍数据库的存取和SQLAlchemy的使用,数据库选择MySQL数据库

    相关文章

      网友评论

          本文标题:搭建一个简单的分布式系统(1)

          本文链接:https://www.haomeiwen.com/subject/esfydttx.html