Ubuntu 安装与配置

本节描述了如何在 Ubuntu 14.04 (LTS) 上安装和配置消息传递服务。

本节假定您已经拥有一个可用的 OpenStack 环境,并且至少安装了身份服务。

您可以在此处找到有关在小型配置中安装消息传递服务的说明和推荐设置:一台 Web 服务器,配置消息传递服务以使用三个 MongoDB 数据库服务器的副本集。由于仅使用一台 Web 服务器,因此使用这些说明安装的消息传递服务不能被认为是高可用的,请参阅 安装和配置

在本教程中,将使用以下服务器名称作为示例

  • 带有消息传递服务的 Web 服务器:WEB0.EXAMPLE-MESSAGES.NET

  • 数据库服务器:MYDB0.EXAMPLE-MESSAGES.NETMYDB1.EXAMPLE-MESSAGES.NETMYDB2.EXAMPLE-MESSAGES.NET

  • 身份服务服务器:IDENTITY.EXAMPLE-MESSAGES.NET

先决条件

在您安装消息传递服务之前,您必须满足以下系统要求

  • 已安装身份服务,用于用户和项目管理。

  • Python 2.7。

在您安装和配置消息传递之前,您必须创建三个数据库服务器的 MongoDB 副本集。您还需要在身份服务中创建服务凭证和 API 端点。

  1. 在数据库服务器上安装和配置 MongoDB 副本集

    1. 在数据库服务器上安装 MongoDB

      在每个数据库服务器上,请遵循官方 MongoDB 安装说明

      注意

      消息传递服务与 MongoDB 版本 >= 2.4 兼容

    2. 在数据库服务器上配置 MongoDB

      在每个数据库服务器上编辑配置文件:/etc/mongod.conf 并根据需要进行修改

      # MongoDB sample configuration for Messaging service.
      # (For MongoDB version >= 2.6)
      # Edit according to your needs.
      systemLog:
        destination: file
        logAppend: true
        path: /var/log/mongodb/mongod.log
      
      storage:
        dbPath: /var/lib/mongo
        journal:
          enabled: false
      
      processManagement:
        fork: true  # fork and run in background
        pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile
      
      net:
        port: 27017
        # bindIp: 127.0.0.1  # Listen to local interface only, comment to listen on all interfaces.
      
      operationProfiling:
         slowOpThresholdMs: 200
         mode: slowOp
      
      replication:
         oplogSizeMB: 2048
         replSetName: catalog
      

      注意

      对于较旧的 MongoDB 版本(2.4 和 2.5),配置文件应以不同的格式编写。有关不同版本的格式信息,请参阅官方 MongoDB 配置参考

      警告

      需要额外的步骤来保护 MongoDB 安装。您应该根据您的安全要求修改此配置。请参阅官方 MongoDB 安全参考

    3. 在数据库服务器上启动 MongoDB

      在所有数据库服务器上启动 MongoDB 服务

      # service mongodb start
      
    4. 在数据库服务器上配置 MongoDB 副本集

      在您已在三台服务器上安装 MongoDB,并且假设主 MongoDB 服务器的主机名为 MYDB0.EXAMPLE-MESSAGES.NET,则转到 MYDB0 并运行以下命令

      # mongo local --eval "printjson(rs.initiate())"
      # mongo local --eval "printjson(rs.add('MYDB1.EXAMPLE-MESSAGES.NET'))"
      # mongo local --eval "printjson(rs.add('MYDB2.EXAMPLE-MESSAGES.NET'))"
      

      注意

      数据库服务器必须可以相互访问,并且也必须可以从消息传递服务 Web 服务器访问。配置所有数据库服务器上的防火墙,以接受来自所需源的端口 27017 上的传入连接。

      要检查副本集是否已建立,请查看此命令的输出

      # mongo local --eval "printjson(rs.status())"
      
  2. 激活 admin 凭证以访问仅管理员可用的 CLI 命令

    $ . admin-openrc
    
  3. 要创建服务凭证,请完成以下步骤

    1. 创建 zaqar 用户

      $ openstack user create --domain default --password-prompt zaqar
      User Password:
      Repeat User Password:
      +-----------+----------------------------------+
      | Field     | Value                            |
      +-----------+----------------------------------+
      | domain_id | default                          |
      | enabled   | True                             |
      | id        | 7b0ffc83097148dab6ecbef6ddcc46bf |
      | name      | zaqar                            |
      +-----------+----------------------------------+
      
    2. admin 角色添加到 zaqar 用户

      $ openstack role add --project service --user zaqar admin
      

      注意

      此命令不会产生任何输出。

    3. 创建 zaqar 服务实体

      $ openstack service create --name zaqar --description "Messaging" messaging
      +-------------+----------------------------------+
      | Field       | Value                            |
      +-------------+----------------------------------+
      | description | Messaging                        |
      | enabled     | True                             |
      | id          | b39c22818be5425ba2315dd4b10cd57c |
      | name        | zaqar                            |
      | type        | messaging                        |
      +-------------+----------------------------------+
      
  4. 创建消息传递服务 API 端点

    $ openstack endpoint create --region RegionOne messaging public http://WEB0.EXAMPLE-MESSAGES.NET:8888
    +--------------+---------------------------------------+
    | Field        | Value                                 |
    +--------------+---------------------------------------+
    | enabled      | True                                  |
    | id           | aabca78860e74c4db0bcb36167bfe106      |
    | interface    | public                                |
    | region       | RegionOne                             |
    | region_id    | RegionOne                             |
    | service_id   | b39c22818be5425ba2315dd4b10cd57c      |
    | service_name | zaqar                                 |
    | service_type | messaging                             |
    | url          | http://WEB0.EXAMPLE-MESSAGES.NET:8888 |
    +--------------+---------------------------------------+
    
    $ openstack endpoint create --region RegionOne messaging internal http://WEB0.EXAMPLE-MESSAGES.NET:8888
    +--------------+---------------------------------------+
    | Field        | Value                                 |
    +--------------+---------------------------------------+
    | enabled      | True                                  |
    | id           | 07f9524613de4fd3905e13a87f81fd3f      |
    | interface    | internal                              |
    | region       | RegionOne                             |
    | region_id    | RegionOne                             |
    | service_id   | b39c22818be5425ba2315dd4b10cd57c      |
    | service_name | zaqar                                 |
    | service_type | messaging                             |
    | url          | http://WEB0.EXAMPLE-MESSAGES.NET:8888 |
    +--------------+---------------------------------------+
    
    $ openstack endpoint create --region RegionOne messaging admin http://WEB0.EXAMPLE-MESSAGES.NET:8888
    +--------------+---------------------------------------+
    | Field        | Value                                 |
    +--------------+---------------------------------------+
    | enabled      | True                                  |
    | id           | 686f7b19428f4b5aa1425667dfe4f49d      |
    | interface    | admin                                 |
    | region       | RegionOne                             |
    | region_id    | RegionOne                             |
    | service_id   | b39c22818be5425ba2315dd4b10cd57c      |
    | service_name | zaqar                                 |
    | service_type | messaging                             |
    | url          | http://WEB0.EXAMPLE-MESSAGES.NET:8888 |
    +--------------+---------------------------------------+
    

安装和配置消息传递 Web 服务器

在 Web 服务器 WEB0.EXAMPLE-MESSAGES.NET 上安装和配置 memcacheduWSGI 和消息传递。

  1. 为了缓存身份服务令牌和目录映射,请在 Web 服务器 WEB0.EXAMPLE-MESSAGES.NET 上安装 memcached

    # apt-get install memcached
    

    启动 memcached 服务

    # service memcached start
    
  2. 安装消息传递服务和 uWSGI

    # apt-get install python-pip
    # git clone https://git.openstack.org/openstack/zaqar.git
    # cd zaqar
    # pip install . -r ./requirements.txt --upgrade --log /tmp/zaqar-pip.log
    # pip install --upgrade pymongo gevent uwsgi
    
  3. 创建 Zaqar 配置文件目录 /etc/zaqar/

    # mkdir /etc/zaqar
    
  4. 自定义策略文件

    # oslopolicy-sample-generator --config-file etc/zaqar-policy-generator.conf
    # cp etc/zaqar.policy.yaml.sample /etc/zaqar/policy.yaml
    

    根据需要编辑 policy.yaml 中的任何项目。

    注意

    默认情况下,如果您不需要自定义策略文件,则无需执行上述步骤,然后 zaqar 将使用代码的默认策略。

  5. 创建日志文件

    # touch /var/log/zaqar-server.log
    # chown ZAQARUSER:ZAQARUSER /var/log/zaqar-server.log
    # chmod 600 /var/log/zaqar-server.log
    

    ZAQARUSER 替换为系统中使用户名,消息传递服务将在该用户下运行。

  6. 创建 /srv/zaqar 文件夹以存储 uWSGI 配置文件

    # mkdir /srv/zaqar
    
  7. 使用以下内容创建 /srv/zaqar/zaqar_uwsgi.py

    from keystonemiddleware import auth_token
    from zaqar.transport.wsgi import app
    
    app = auth_token.AuthProtocol(app.app, {})
    
  8. 增加默认的 backlog 监听限制 (128)

    # echo "net.core.somaxconn=2048" | sudo tee --append /etc/sysctl.conf
    
  9. 使用以下内容创建 /srv/zaqar/uwsgi.ini 文件并根据需要进行修改

    [uwsgi]
    https = WEB0.EXAMPLE-MESSAGES.NET:8888,PATH_TO_SERVER_CRT,PATH_TO_SERVER_PRIVATE_KEY
    pidfile = /var/run/zaqar.pid
    gevent = 2000
    gevent-monkey-patch = true
    listen = 1024
    enable-threads = true
    chdir = /srv/zaqar
    module = zaqar_uwsgi:app
    workers = 4
    harakiri = 60
    add-header = Connection: close
    

    PATH_TO_SERVER_CRT 替换为服务器证书 (*.crt) 的路径,并将 PATH_TO_SERVER_PRIVATE_KEY 替换为服务器私钥 (*.key) 的路径。

    注意

    上述 uWSGI 配置选项可以根据不同的安全性和性能要求进行修改,包括负载均衡。请参阅官方 uWSGI 配置参考

  10. 创建 pid 文件

    # touch /var/run/zaqar.pid
    # chown ZAQARUSER:ZAQARUSER /var/run/zaqar.pid
    

    ZAQARUSER 替换为系统中使用户名,消息传递服务将在该用户下运行。

  11. 创建消息传递服务的配置文件 /etc/zaqar/zaqar.conf,内容如下

    [DEFAULT]
    # Show debugging output in logs (sets DEBUG log level output)
    #debug = False
    
    # Pooling and admin mode configs
    pooling      = True
    admin_mode    = True
    
    # Log to file
    log_file = /var/log/zaqar-server.log
    
    # This is taken care of in our custom app.py, so disable here
    ;auth_strategy = keystone
    
    # Modify to make it work with your Identity service.
    [keystone_authtoken]
    project_domain_name = Default
    user_domain_name = Default
    project_domain_id = default
    project_name = service
    user_domain_id = default
    # File path to a PEM encoded Certificate Authority to use when verifying
    # HTTPs connections. Defaults to system CAs if commented.
    cafile = PATH_TO_CA_FILE
    # Messaging service user name in Identity service.
    username = ZAQARIDENTITYUSER
    # Messaging service password in Identity service.
    password = ZAQARIDENTITYPASSWORD
    # Complete public Identity API endpoint (HTTPS protocol is more preferable
    # than HTTP).
    www_authenticate_uri = HTTPS://IDENTITY.EXAMPLE-MESSAGES.NET:5000
    # Complete admin Identity API endpoint (HTTPS protocol is more preferable
    # than HTTP).
    identity_uri = HTTPS://IDENTITY.EXAMPLE-MESSAGES.NET:5000
    # Token cache time in seconds.
    token_cache_time = TOKEN_CACHE_TIME
    memcached_servers = 127.0.0.1:11211
    
    [cache]
    # Dogpile.cache backend module. It is recommended that Memcache with
    # pooling (oslo_cache.memcache_pool) or Redis (dogpile.cache.redis) be
    # used in production deployments. Small workloads (single process)
    # like devstack can use the dogpile.cache.memory backend. (string
    # value)
    backend = dogpile.cache.memory
    memcache_servers = 127.0.0.1:11211
    
    [drivers]
    transport = wsgi
    message_store = mongodb
    management_store = mongodb
    
    [drivers:management_store:mongodb]
    # Mongodb Connection URI. If ssl connection enabled, then ssl_keyfile,
    # ssl_certfile, ssl_cert_reqs, ssl_ca_certs options need to be set
    # accordingly.
    uri = mongodb://MYDB0.EXAMPLE-MESSAGES.NET,MYDB1.EXAMPLE-MESSAGES.NET,MYDB2.EXAMPLE-MESSAGES.NET:27017/?replicaSet=catalog&w=2&readPreference=secondaryPreferred
    
    # Name for the database on mongodb server.
    database = zaqarmanagementstore
    
    # Number of databases across which to partition message data, in order
    # to reduce writer lock %. DO NOT change this setting after initial
    # deployment. It MUST remain static. Also, you should not need a large
    # number of partitions to improve performance, esp. if deploying
    # MongoDB on SSD storage. (integer value)
    partitions = 8
    
    # Uncomment any options below if needed.
    
    # Maximum number of times to retry a failed operation. Currently
    # only used for retrying a message post.
    ;max_attempts = 1000
    
    # Maximum sleep interval between retries (actual sleep time
    # increases linearly according to number of attempts performed).
    ;max_retry_sleep = 0.1
    
    # Maximum jitter interval, to be added to the sleep interval, in
    # order to decrease probability that parallel requests will retry
    # at the same instant.
    ;max_retry_jitter = 0.005
    
    # Frequency of message garbage collections, in seconds
    ;gc_interval = 5 * 60
    
    # Threshold of number of expired messages to reach in a given
    # queue, before performing the GC. Useful for reducing frequent
    # locks on the DB for non-busy queues, or for worker queues
    # which process jobs quickly enough to keep the number of in-
    # flight messages low.
    #
    # Note: The higher this number, the larger the memory-mapped DB
    # files will be.
    ;gc_threshold = 1000
    
    [drivers:message_store:mongodb]
    # This section has same set of available options as
    # "[drivers:management_store:mongodb]" section.
    #
    # If pooling is enabled, all pools inherit values from options in these
    # settings unless overridden in pool creation request. Also "uri" option
    # value isn't used in case of pooling.
    #
    # If ssl connection enabled, then ssl_keyfile, ssl_certfile, ssl_cert_reqs,
    # ssl_ca_certs options need to be set accordingly.
    
    # Name for the database on MondoDB server.
    database = zaqarmessagestore
    
    [transport]
    max_queues_per_page = 1000
    max_queue_metadata = 262144
    max_mesages_per_page = 10
    max_messages_post_size = 262144
    max_message_ttl = 1209600
    max_claim_ttl = 43200
    max_claim_grace = 43200
    
    [signed_url]
    # Secret key used to encrypt pre-signed URLs. (string value)
    secret_key = SOMELONGSECRETKEY
    

    根据需要编辑任何选项,尤其是带有大写值的选项。

  12. 创建一个 upstart 配置文件,可以命名为 /etc/init/zaqar.conf

    description "Zaqar api server"
    author "Your Name <yourname@example.com>"
    
    start on runlevel [2345]
    stop on runlevel [!2345]
    
    chdir /var/run
    
    pre-start script
        mkdir -p /var/run/zaqar
        chown zaqar:zaqar /var/run/zaqar
    
        mkdir -p /var/lock/zaqar
        chown zaqar:root /var/lock/zaqar
    end script
    
    exec /usr/bin/uwsgi --master --emperor /etc/zaqar/uwsgi
    

完成安装

现在,在您已配置 Web 服务器和数据库服务器以拥有功能性的消息传递服务之后,您需要启动该服务,使该服务在系统重新启动时自动启动,并将创建的 MongoDB 副本集定义为消息传递的池。

  1. 在 Web 服务器上启动消息传递服务

    # systemctl start zaqar.uwsgi.service
    
  2. 使消息传递服务在 Web 服务器上重新启动后自动启动

    # systemctl enable zaqar.uwsgi.service
    
  3. 配置池

    # curl -i -X PUT https://WEB0.EXAMPLE-MESSAGES.NET:8888/v2/pools/POOL1 \
               -d '{"weight": 100, "uri": "mongodb://MYDB0.EXAMPLE-MESSAGES.NET,MYDB1.EXAMPLE-MESSAGES.NET,MYDB2.EXAMPLE-MESSAGES.NET:27017/?replicaSet=catalog&w=2&readPreference=secondaryPreferred", "options": {"partitions": 8}}' \
               -H "Client-ID: CLIENT_ID" \
               -H "X-Auth-Token: TOKEN" \
               -H "Content-type: application/json" \
    

    POOL1 变量替换为所需的池名称。

    CLIENT_ID 变量替换为通用唯一标识符 (UUID),例如,可以使用 uuidgen 实用程序生成。

    TOKEN 变量替换为从身份服务检索到的身份验证令牌。如果您选择不启用 Keystone 身份验证,则无需传递令牌。

    注意

    上述 curl 请求中的 options 键会覆盖配置文件或默认值中 [drivers:message_store:mongodb] 消息传递服务配置文件的部分中的任何选项。

提示

在更大的部署中,应该有许多负载均衡的 Web 服务器。此外,管理存储数据库和消息存储数据库(池)应该位于不同的 MongoDB 副本集上。