Giter VIP home page Giter VIP logo

sanic-ms's Introduction

Sanic Micro Service

基于sanic的微服务基础架构

Introduce

使用python做web开发面临的一个最大的问题就是性能,在解决C10K问题上显的有点吃力。有些异步框架Tornado、Twisted、Gevent 等就是为了解决性能问题。这些框架在性能上有些提升,但是也出现了各种古怪的问题难以解决。

在python3.6中,官方的异步协程库asyncio正式成为标准。在保留便捷性的同时对性能有了很大的提升,已经出现许多的异步框架使用asyncio。

使用较早的异步框架是aiohttp,它提供了server端和client端,对asyncio做了很好的封装。但是开发方式和最流行的微框架flask不同,flask开发简单,轻量,高效。将两者结合起来就有了sanic。

Sanic框架是和Flask相似异步协程框架,简单轻量,并且性能很高。本项目就是以sanic为基础搭建的微服务框架。微服务最近很火,它解决了复杂性问题,提高开发效率,便于部署等优点。

正是结合这些优点, 以sanic为基础,集成多个流行的库搭建微服务框架。

Feature

  • 使用sanic异步框架,简单,轻量,高效。
  • 使用uvloop为核心引擎,使sanic在很多情况下单机并发甚至不亚于Golang。
  • 使用asyncpg为数据库驱动,进行数据库连接,执行sql语句执行。
  • 使用aiohttp为Client,对其他微服务进行访问。
  • 使用peewee为ORM,但是只是用来做模型设计和migration。
  • 使用opentracing为分布式追踪系统。
  • 使用unittest做单元测试,并且使用mock来避免访问其他微服务。
  • 使用swagger做API标准,能自动生成API文档。

Usage

Example

Swagger API

image

Zipkin Server

image image

Config

设置配置文件和Django相似,通过设置环境变量值SANIC_CONFIG_MODULE

export SANIC_CONFIG_MODULE='mysite.configs'

Server

使用sanic异步框架,有较高的性能,但是使用不当会造成blocking, 对于有IO请求的都要选用异步库。添加库要慎重。 sanic使用uvloop异步驱动,uvloop基于libuv使用Cython编写,性能比nodejs还要高。

功能说明:

Before Server Start

  • 创建DB连接池
  • 创建Client连接
  • 创建queue, 用于日志追踪
  • 创建opentracing.tracer进行日志追踪

Middleware

  • 处理跨域请求
  • 创建span, 用于日志追踪
  • 对response进行封装,统一格式

Error Handler

对抛出的异常进行处理,返回统一格式

Task

创建task消费queue中对span,用于日志追踪

Asynchronous Handler

由于使用的是异步框架,可以将一些IO请求并行处理

Example:

async def async_request(datas):
    # async handler request
    results = await asyncio.gather(*[data[2] for data in datas])
    for index, obj in enumerate(results):
        data = datas[index]
        data[0][data[1]] = results[index]

@user_bp.get('/<id:int>')
@doc.summary("get user info")
@doc.description("get user info by id")
@doc.produces(Users)
async def get_users_list(request, id):
    async with request.app.db.acquire(request) as cur:
        record = await cur.fetch(
            """ SELECT * FROM users WHERE id = $1 """, id)
        datas = [
            [record, 'city_id', get_city_by_id(request, record['city_id'])]
            [record, 'role_id', get_role_by_id(request, record['role_id'])]
        ]
        await async_request(datas)
        return record

get_city_by_id, get_role_by_id是并行处理。

相关连接

sanic

Model & Migration

Peewee is a simple and small ORM. It has few (but expressive) concepts, making it easy to learn and intuitive to use。

ORM使用peewee, 只是用来做模型设计和migration, 数据操作使用asyncpg。

Example:

# models.py

class Users(Model):
    id = PrimaryKeyField()
    create_time = DateTimeField(verbose_name='create time',
                                default=datetime.datetime.utcnow)
    name = CharField(max_length=128, verbose_name="user's name")
    age = IntegerField(null=False, verbose_name="user's age")
    sex = CharField(max_length=32, verbose_name="user's sex")
    city_id = IntegerField(verbose_name='city for user', help_text=CityApi)
    role_id = IntegerField(verbose_name='role for user', help_text=RoleApi)

    class Meta:
        db_table = 'users'


# migrations.py

from sanicms.migrations import MigrationModel, info, db

class UserMigration(MigrationModel):
    _model = Users

    # @info(version="v1")
    # def migrate_v1(self):
    #     migrate(self.add_column('sex'))

def migrations():
    try:
        um = UserMigration()
        with db.transaction():
            um.auto_migrate()
            print("Success Migration")
    except Exception as e:
        raise e

if __name__ == '__main__':
    migrations()
  • 运行命令 python migrations.py
  • migrate_v1函数添加字段sex, 在BaseModel中要先添加name字段
  • info装饰器会创建表migrate_record来记录migrate,version每个model中必须唯一,使用version来记录是否执行过,还可以记录author,datetime
  • migrate函数必须以**migrate_**开头

相关连接

peewee

DB

asyncpg is the fastest driver among common Python, NodeJS and Go implementations

使用asyncpg为数据库驱动, 对数据库连接进行封装, 执行数据库操作。

不使用ORM做数据库操作,一个原因是性能,ORM会有性能的损耗,并且无法使用asyncpg高性能库。另一个是单个微服务是很简单的,表结构不会很复杂,简单的SQL语句就可以处理来,没必要引入ORM。

Example:

sql = "SELECT * FROM users WHERE name=$1"
name = "test"
async with request.app.db.acquire(request) as cur:
    data = await cur.fetchrow(sql, name)

async with request.app.db.transaction(request) as cur:
    data = await cur.fetchrow(sql, name)
  • acquire() 函数为非事务, 对于只涉及到查询的使用非事务,可以提高查询效率
  • tansaction() 函数为事务操作,对于增删改必须使用事务操作
  • 传入request参数是为了获取到span,用于日志追踪
  • TODO 数据库读写分离

相关连接

asyncpg benchmarks

Client

使用aiohttp中的client,对客户端进行了简单的封装,访问其他微服务。

Don’t create a session per request. Most likely you need a session per application which performs all requests altogether. A session contains a connection pool inside, connection reusage and keep-alives (both are on by default) may speed up total performance.

Example:

@app.listener('before_server_start')
async def before_srver_start(app, loop):
    app.client =  Client(loop, url='http://host:port')

async def get_role_by_id(request, id):
    cli = request.app.client.cli(request)
    async with cli.get('/cities/{}'.format(id)) as res:
        return await res.json()

@app.listener('before_server_stop')
async def before_server_stop(app, loop):
    app.client.close()

对于访问不同的微服务可以创建多个不同的client,这样每个client都会keep-alives

相关连接

aiohttp

LOG & Distributed Tracing System

使用官方logging, 配置文件为logging.yml, sanic版本要0.6.0及以上。JsonFormatter将日志转成json格式,用于输入到ES

Enter OpenTracing: by offering consistent, expressive, vendor-neutral APIs for popular platforms, OpenTracing makes it easy for developers to add (or switch) tracing implementations with an O(1) configuration change. OpenTracing also offers a lingua franca for OSS instrumentation and platform-specific tracing helper libraries. Please refer to the Semantic Specification.

装饰器logger

@logger(type='method', category='test', detail='detail', description="des", tracing=True, level=logging.INFO)
async def get_city_by_id(request, id):
    cli = request.app.client.cli(request)
  • type: 日志类型,如 method, route
  • category: 日志类别,默认为app的name
  • detail: 日志详细信息
  • description: 日志描述,默认为函数的注释
  • tracing: 日志追踪,默认为True
  • level: 日志级别,默认为INFO

分布式追踪系统

  • OpenTracing是以Dapper,Zipkin等分布式追踪系统为依据, 为分布式追踪建立了统一的标准。
  • Opentracing跟踪每一个请求,记录请求所经过的每一个微服务,以链条的方式串联起来,对分析微服务的性能瓶颈至关重要。
  • 使用opentracing框架,但是在输出时转换成zipkin格式。 因为大多数分布式追踪系统考虑到性能问题,都是使用的thrift进行通信的,本着简单,Restful风格的精神,没有使用RPC通信。以日志的方式输出, 可以使用fluentd, logstash等日志收集再输入到Zipkin。Zipkin是支持HTTP输入的。
  • 生成的span先无阻塞的放入queue中,在task中消费队列的span。后期可以添加上采样频率。
  • 对于DB,Client都加上了tracing

相关连接

opentracing zipkin jaeger

API

api文档使用swagger标准。

Example:

from sanicms import doc

@user_bp.post('/')
@doc.summary('create user')
@doc.description('create user info')
@doc.consumes(Users)
@doc.produces({'id': int})
async def create_user(request):
    data = request['data']
    async with request.app.db.transaction(request) as cur:
        record = await cur.fetchrow(
            """ INSERT INTO users(name, age, city_id, role_id)
                VALUES($1, $2, $3, $4, $5)
                RETURNING id
            """, data['name'], data['age'], data['city_id'], data['role_id']
        )
        return {'id': record['id']}
  • summary: api概要
  • description: 详细描述
  • consumes: request的body数据
  • produces: response的返回数据
  • tag: API标签
  • 在consumes和produces中传入的参数可以是peewee的model,会解析model生成API数据, 在field字段的help_text参数来表示引用对象
  • http://host:ip/openapi/spec.json 获取生成的json数据

相关连接

swagger

Response

在返回时,不要返回response,直接返回原始数据,会在Middleware中对返回的数据进行处理,返回统一的格式,具体的格式可以查看

Unittest

单元测试使用unittest

Example:

from sanicms.tests import APITestCase
from service.server import app

class TestCase(APITestCase):
    _app = app
    _blueprint = 'visit'

    def setUp(self):
        super(TestCase, self).setUp()
        self._mock.get('/cities/1',
                       payload={'id': 1, 'name': 'shanghai'})
        self._mock.get('/roles/1',
                       payload={'id': 1, 'name': 'shanghai'})

    def test_create_user(self):
        data = {
            'name': 'test',
            'age': 2,
            'city_id': 1,
            'role_id': 1,
        }
        res = self.client.create_user(data=data)
        body = ujson.loads(res.text)
        self.assertEqual(res.status, 200)
  • 其中_blueprint为blueprint名称
  • 在setUp函数中,使用_mock来注册mock信息, 这样就不会访问真实的服务器, payload为返回的body信息
  • 使用client变量调用各个函数, data为body信息,params为路径的参数信息,其他参数是route的参数

coverage

coverage erase
coverage run --source . -m sanicms tests
coverage xml -o reports/coverage.xml
coverage2clover -i reports/coverage.xml -o reports/clover.xml
coverage html -d reports
  • coverage2colver 是将coverage.xml 转换成 clover.xml,bamboo需要的格式是clover的。

相关连接

unittest coverage

Exception

使用 app.error_handler = CustomHander() 对抛出的异常进行处理

Example:

from sanicms.exception import ServerError

@visit_bp.delete('/users/<id:int>')
async def del_user(request, id):
    raise ServerError(error='内部错误',code='10500', message="msg")
  • code: 错误码,无异常时为0,其余值都为异常
  • message: 状态码信息
  • error: 自定义错误信息
  • status_code: http状态码,使用标准的http状态码

sanic-ms's People

Contributors

hjc1702 avatar songcser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sanic-ms's Issues

opentracing版本兼容性问题

opentracing==1.2.2 对python版本是>2.6 <3
sanic对python版本要求是3.5以上
请问你是如何解决这兼容性问题?
谢谢

通过docker-compose编排借助docker stack部署服务启动顺序的问题,未等待DB完全启动导致整体部署失败

嗨,你好。@songcser
问题描述:通过docker-compose编排借助docker stack部署服务启动顺序的问题,未等待DB完全启动从而导致整体部署失败。
操作流程:运行examples目录下 ./develop/cluster.sh脚本。
错误日志: 运行docker service logs ms_user_server 得到如下错误

ms_user_server.2.qatzo70vl9bq@ms-node2    | [2018-11-17 08:10:35 +0000] [1] [DEBUG]
ms_user_server.2.qatzo70vl9bq@ms-node2    |                  ▄▄▄▄▄
ms_user_server.2.qatzo70vl9bq@ms-node2    |         ▀▀▀██████▄▄▄       _______________
ms_user_server.2.qatzo70vl9bq@ms-node2    |       ▄▄▄▄▄  █████████▄  /                 \
ms_user_server.2.qatzo70vl9bq@ms-node2    |      ▀▀▀▀█████▌ ▀▐▄ ▀▐█ |   Gotta go fast!  |
ms_user_server.2.qatzo70vl9bq@ms-node2    |    ▀▀█████▄▄ ▀██████▄██ | _________________/
ms_user_server.2.qatzo70vl9bq@ms-node2    |    ▀▄▄▄▄▄  ▀▀█▄▀█════█▀ |/
ms_user_server.2.qatzo70vl9bq@ms-node2    |         ▀▀▀▄  ▀▀███ ▀       ▄▄
ms_user_server.2.qatzo70vl9bq@ms-node2    |      ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌
ms_user_server.2.qatzo70vl9bq@ms-node2    |    ██▀▄▄▄██▀▄███▀ ▀▀████      ▄██
ms_user_server.2.qatzo70vl9bq@ms-node2    | ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███     ▌▄▄▀
ms_user_server.2.qatzo70vl9bq@ms-node2    | ▌    ▐▀████▐███▒▒▒▒▒▐██▌
ms_user_server.2.qatzo70vl9bq@ms-node2    | ▀▄▄▄▄▀   ▀▀████▒▒▒▒▄██▀
ms_user_server.2.qatzo70vl9bq@ms-node2    |           ▀▀█████████▀
ms_user_server.2.qatzo70vl9bq@ms-node2    |         ▄▄██▀██████▀█
ms_user_server.2.qatzo70vl9bq@ms-node2    |       ▄██▀     ▀▀▀  █
ms_user_server.2.qatzo70vl9bq@ms-node2    |      ▄█             ▐▌
ms_user_server.2.qatzo70vl9bq@ms-node2    |  ▄▄▄▄█▌              ▀█▄▄▄▄▀▀▄
ms_user_server.2.qatzo70vl9bq@ms-node2    | ▌     ▐                ▀▀▄▄▄▀
ms_user_server.2.qatzo70vl9bq@ms-node2    |  ▀▀▄▄▀
ms_user_server.2.qatzo70vl9bq@ms-node2    |
ms_user_server.2.qatzo70vl9bq@ms-node2    | [2018-11-17 08:10:35 +0000] [1] [INFO] Goin' Fast @ http://0.0.0.0:8030
ms_user_server.2.qatzo70vl9bq@ms-node2    | Executing <Task pending coro=<before_server_start() running at /usr/local/lib/python3.6/site-packages/sanicms/server.py:46> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7fcefda7d4c8>()] created at /usr/local/lib/python3.6/asyncio/tasks.py:341> cb=[run_until_complete.<locals>.<lambda>()] created at /usr/local/lib/python3.6/site-packages/sanic/server.py:503> took 1.004 seconds
ms_user_server.2.qatzo70vl9bq@ms-node2    | {"hostname": "f6fd17cc4c04", "name": "sanic", "args": [], "levelname": "INFO", "levelno": 20, "pathname": "/usr/local/lib/python3.6/site-packages/sanicms/service.py", "filename": "service.py", "module": "service", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 104, "funcName": "service_watcher", "created": 1542442242.8082986, "msecs": 808.2985877990723, "relativeCreated": 6910.207986831665, "thread": 140527157484360, "threadName": "MainThread", "processName": "MainProcess", "process": 20, "message": "service watcher...", "index": "sanic", "document_type": "sanic", "@version": 1, "@timestamp": "2018-11-17T08:10:42.808Z"}
ms_user_server.2.qatzo70vl9bq@ms-node2    | [2018-11-17 08:10:42 +0000] [20] [ERROR] Experienced exception while trying to serve
ms_user_server.2.qatzo70vl9bq@ms-node2    | Traceback (most recent call last):
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanic/app.py", line 730, in run
ms_user_server.2.qatzo70vl9bq@ms-node2    |     serve(**server_settings)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 609, in serve
ms_user_server.2.qatzo70vl9bq@ms-node2    |     trigger_events(before_start, loop)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 503, in trigger_events
ms_user_server.2.qatzo70vl9bq@ms-node2    |     loop.run_until_complete(result)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "uvloop/loop.pyx", line 1446, in uvloop.loop.Loop.run_until_complete
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanicms/server.py", line 46, in before_server_start
ms_user_server.2.qatzo70vl9bq@ms-node2    |     app.db = await ConnectionPool(loop=loop).init(app.config['DB_CONFIG'])
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanicms/db.py", line 142, in init
ms_user_server.2.qatzo70vl9bq@ms-node2    |     self._pool = await create_pool(**config, loop=self._loop, max_size=100)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 398, in _async__init__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     await self._initialize()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 415, in _initialize
ms_user_server.2.qatzo70vl9bq@ms-node2    |     await first_ch.connect()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 125, in connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     self._con = await self._pool._get_new_connection()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 461, in _get_new_connection
ms_user_server.2.qatzo70vl9bq@ms-node2    |     **self._connect_kwargs)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connection.py", line 1688, in connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     max_cacheable_statement_size=max_cacheable_statement_size)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 551, in _connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     raise last_error
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 543, in _connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     connection_class=connection_class)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 513, in _connect_addr
ms_user_server.2.qatzo70vl9bq@ms-node2    |     connector, timeout=timeout, loop=loop)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return fut.result()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "uvloop/loop.pyx", line 1879, in create_connection
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "uvloop/loop.pyx", line 1858, in uvloop.loop.Loop.create_connection
ms_user_server.2.qatzo70vl9bq@ms-node2    | ConnectionRefusedError: [Errno 111] Connection refused
ms_user_server.2.qatzo70vl9bq@ms-node2    | {"hostname": "f6fd17cc4c04", "name": "sanic.error", "args": [], "levelname": "ERROR", "levelno": 40, "pathname": "/usr/local/lib/python3.6/site-packages/sanic/app.py", "filename": "app.py", "module": "app", "exc_info": ["<class 'ConnectionRefusedError'>", "[Errno 111] Connection refused", "<traceback object at 0x7fcefb7d7688>"], "stack_info": null, "lineno": 735, "funcName": "run", "created": 1542442242.9068415, "msecs": 906.841516494751, "relativeCreated": 7008.750915527344, "thread": 140527157484360, "threadName": "MainThread", "processName": "MainProcess", "process": 20, "message": "Experienced exception while trying to serve", "asctime": "[2018-11-17 08:10:42 +0000]", "exception": "Traceback (most recent call last):\n  File \"/usr/local/lib/python3.6/site-packages/sanic/app.py\", line 730, in run\n    serve(**server_settings)\n  File \"/usr/local/lib/python3.6/site-packages/sanic/server.py\", line 609, in serve\n    trigger_events(before_start, loop)\n  File \"/usr/local/lib/python3.6/site-packages/sanic/server.py\", line 503, in trigger_events\n    loop.run_until_complete(result)\n  File \"uvloop/loop.pyx\", line 1446, in uvloop.loop.Loop.run_until_complete\n  File \"/usr/local/lib/python3.6/site-packages/sanicms/server.py\", line 46, in before_server_start\n    app.db = await ConnectionPool(loop=loop).init(app.config['DB_CONFIG'])\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/sanicms/db.py\", line 142, in init\n    self._pool = await create_pool(**config, loop=self._loop, max_size=100)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 398, in _async__init__\n    await self._initialize()\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 415, in _initialize\n    await first_ch.connect()\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 125, in connect\n    self._con = await self._pool._get_new_connection()\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 461, in _get_new_connection\n    **self._connect_kwargs)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connection.py\", line 1688, in connect\n    max_cacheable_statement_size=max_cacheable_statement_size)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py\", line 551, in _connect\n    raise last_error\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py\", line 543, in _connect\n    connection_class=connection_class)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py\", line 513, in _connect_addr\n    connector, timeout=timeout, loop=loop)\n  File \"/usr/local/lib/python3.6/asyncio/tasks.py\", line 358, in wait_for\n    return fut.result()\n  File \"uvloop/loop.pyx\", line 1879, in create_connection\n  File \"uvloop/loop.pyx\", line 1858, in uvloop.loop.Loop.create_connection\nConnectionRefusedError: [Errno 111] Connection refused", "index": "sanic.error", "document_type": "sanic.error", "@version": 1, "@timestamp": "2018-11-17T08:10:42.908Z"}
ms_user_server.2.qatzo70vl9bq@ms-node2    | Traceback (most recent call last):
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/service/server.py", line 28, in <module>
ms_user_server.2.qatzo70vl9bq@ms-node2    |     app.run(host="0.0.0.0", port=app.config['PORT'], debug=True)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanic/app.py", line 730, in run
ms_user_server.2.qatzo70vl9bq@ms-node2    |     serve(**server_settings)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 609, in serve
ms_user_server.2.qatzo70vl9bq@ms-node2    |     trigger_events(before_start, loop)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 503, in trigger_events
ms_user_server.2.qatzo70vl9bq@ms-node2    |     loop.run_until_complete(result)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "uvloop/loop.pyx", line 1446, in uvloop.loop.Loop.run_until_complete
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanicms/server.py", line 46, in before_server_start
ms_user_server.2.qatzo70vl9bq@ms-node2    |     app.db = await ConnectionPool(loop=loop).init(app.config['DB_CONFIG'])
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/sanicms/db.py", line 142, in init
ms_user_server.2.qatzo70vl9bq@ms-node2    |     self._pool = await create_pool(**config, loop=self._loop, max_size=100)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 398, in _async__init__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     await self._initialize()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 415, in _initialize
ms_user_server.2.qatzo70vl9bq@ms-node2    |     await first_ch.connect()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 125, in connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     self._con = await self._pool._get_new_connection()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 461, in _get_new_connection
ms_user_server.2.qatzo70vl9bq@ms-node2    |     **self._connect_kwargs)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connection.py", line 1688, in connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     max_cacheable_statement_size=max_cacheable_statement_size)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 551, in _connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     raise last_error
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 543, in _connect
ms_user_server.2.qatzo70vl9bq@ms-node2    |     connection_class=connection_class)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return self.gen.send(None)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 513, in _connect_addr
ms_user_server.2.qatzo70vl9bq@ms-node2    |     connector, timeout=timeout, loop=loop)
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
ms_user_server.2.qatzo70vl9bq@ms-node2    |     return fut.result()
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "uvloop/loop.pyx", line 1879, in create_connection
ms_user_server.2.qatzo70vl9bq@ms-node2    |   File "uvloop/loop.pyx", line 1858, in uvloop.loop.Loop.create_connection
ms_user_server.2.qatzo70vl9bq@ms-node2    | ConnectionRefusedError: [Errno 111] Connection refused
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | [2018-11-17 08:10:34 +0000] [1] [DEBUG]
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |                  ▄▄▄▄▄
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |         ▀▀▀██████▄▄▄       _______________
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |       ▄▄▄▄▄  █████████▄  /                 \
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |      ▀▀▀▀█████▌ ▀▐▄ ▀▐█ |   Gotta go fast!  |
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |    ▀▀█████▄▄ ▀██████▄██ | _________________/
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |    ▀▄▄▄▄▄  ▀▀█▄▀█════█▀ |/
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |         ▀▀▀▄  ▀▀███ ▀       ▄▄
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |      ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |    ██▀▄▄▄██▀▄███▀ ▀▀████      ▄██
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███     ▌▄▄▀
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | ▌    ▐▀████▐███▒▒▒▒▒▐██▌
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | ▀▄▄▄▄▀   ▀▀████▒▒▒▒▄██▀
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |           ▀▀█████████▀
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |         ▄▄██▀██████▀█
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |       ▄██▀     ▀▀▀  █
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |      ▄█             ▐▌
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |  ▄▄▄▄█▌              ▀█▄▄▄▄▀▀▄
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | ▌     ▐                ▀▀▄▄▄▀
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |  ▀▀▄▄▀
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | [2018-11-17 08:10:34 +0000] [1] [INFO] Goin' Fast @ http://0.0.0.0:8030
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | Executing <Task pending coro=<before_server_start() running at /usr/local/lib/python3.6/site-packages/sanicms/server.py:46> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7f7169f4a4c8>()] created at /usr/local/lib/python3.6/asyncio/tasks.py:341> cb=[run_until_complete.<locals>.<lambda>()] created at /usr/local/lib/python3.6/site-packages/sanic/server.py:503> took 1.592 seconds
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | {"hostname": "8065c4c7ada4", "name": "sanic", "args": [], "levelname": "INFO", "levelno": 20, "pathname": "/usr/local/lib/python3.6/site-packages/sanicms/service.py", "filename": "service.py", "module": "service", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 104, "funcName": "service_watcher", "created": 1542442239.5656807, "msecs": 565.680742263794, "relativeCreated": 4876.916408538818, "thread": 140125247527752, "threadName": "MainThread", "processName": "MainProcess", "process": 20, "message": "service watcher...", "index": "sanic", "document_type": "sanic", "@version": 1, "@timestamp": "2018-11-17T08:10:39.565Z"}
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | [2018-11-17 08:10:39 +0000] [20] [ERROR] Experienced exception while trying to serve
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | Traceback (most recent call last):
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanic/app.py", line 730, in run
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     serve(**server_settings)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 609, in serve
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     trigger_events(before_start, loop)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 503, in trigger_events
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     loop.run_until_complete(result)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "uvloop/loop.pyx", line 1446, in uvloop.loop.Loop.run_until_complete
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanicms/server.py", line 46, in before_server_start
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     app.db = await ConnectionPool(loop=loop).init(app.config['DB_CONFIG'])
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanicms/db.py", line 142, in init
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     self._pool = await create_pool(**config, loop=self._loop, max_size=100)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 398, in _async__init__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     await self._initialize()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 415, in _initialize
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     await first_ch.connect()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 125, in connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     self._con = await self._pool._get_new_connection()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 461, in _get_new_connection
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     **self._connect_kwargs)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connection.py", line 1688, in connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     max_cacheable_statement_size=max_cacheable_statement_size)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 551, in _connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     raise last_error
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 543, in _connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     connection_class=connection_class)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 513, in _connect_addr
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     connector, timeout=timeout, loop=loop)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return fut.result()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "uvloop/loop.pyx", line 1879, in create_connection
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "uvloop/loop.pyx", line 1858, in uvloop.loop.Loop.create_connection
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | ConnectionRefusedError: [Errno 111] Connection refused
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | {"hostname": "8065c4c7ada4", "name": "sanic.error", "args": [], "levelname": "ERROR", "levelno": 40, "pathname": "/usr/local/lib/python3.6/site-packages/sanic/app.py", "filename": "app.py", "module": "app", "exc_info": ["<class 'ConnectionRefusedError'>", "[Errno 111] Connection refused", "<traceback object at 0x7f7167ca35c8>"], "stack_info": null, "lineno": 735, "funcName": "run", "created": 1542442239.687023, "msecs": 687.0229244232178, "relativeCreated": 4998.258590698242, "thread": 140125247527752, "threadName": "MainThread", "processName": "MainProcess", "process": 20, "message": "Experienced exception while trying to serve", "asctime": "[2018-11-17 08:10:39 +0000]", "exception": "Traceback (most recent call last):\n  File \"/usr/local/lib/python3.6/site-packages/sanic/app.py\", line 730, in run\n    serve(**server_settings)\n  File \"/usr/local/lib/python3.6/site-packages/sanic/server.py\", line 609, in serve\n    trigger_events(before_start, loop)\n  File \"/usr/local/lib/python3.6/site-packages/sanic/server.py\", line 503, in trigger_events\n    loop.run_until_complete(result)\n  File \"uvloop/loop.pyx\", line 1446, in uvloop.loop.Loop.run_until_complete\n  File \"/usr/local/lib/python3.6/site-packages/sanicms/server.py\", line 46, in before_server_start\n    app.db = await ConnectionPool(loop=loop).init(app.config['DB_CONFIG'])\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/sanicms/db.py\", line 142, in init\n    self._pool = await create_pool(**config, loop=self._loop, max_size=100)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 398, in _async__init__\n    await self._initialize()\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 415, in _initialize\n    await first_ch.connect()\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 125, in connect\n    self._con = await self._pool._get_new_connection()\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/pool.py\", line 461, in _get_new_connection\n    **self._connect_kwargs)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connection.py\", line 1688, in connect\n    max_cacheable_statement_size=max_cacheable_statement_size)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py\", line 551, in _connect\n    raise last_error\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py\", line 543, in _connect\n    connection_class=connection_class)\n  File \"/usr/local/lib/python3.6/asyncio/coroutines.py\", line 110, in __next__\n    return self.gen.send(None)\n  File \"/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py\", line 513, in _connect_addr\n    connector, timeout=timeout, loop=loop)\n  File \"/usr/local/lib/python3.6/asyncio/tasks.py\", line 358, in wait_for\n    return fut.result()\n  File \"uvloop/loop.pyx\", line 1879, in create_connection\n  File \"uvloop/loop.pyx\", line 1858, in uvloop.loop.Loop.create_connection\nConnectionRefusedError: [Errno 111] Connection refused", "index": "sanic.error", "document_type": "sanic.error", "@version": 1, "@timestamp": "2018-11-17T08:10:39.692Z"}
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | Traceback (most recent call last):
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/service/server.py", line 28, in <module>
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     app.run(host="0.0.0.0", port=app.config['PORT'], debug=True)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanic/app.py", line 730, in run
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     serve(**server_settings)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 609, in serve
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     trigger_events(before_start, loop)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanic/server.py", line 503, in trigger_events
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     loop.run_until_complete(result)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "uvloop/loop.pyx", line 1446, in uvloop.loop.Loop.run_until_complete
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanicms/server.py", line 46, in before_server_start
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     app.db = await ConnectionPool(loop=loop).init(app.config['DB_CONFIG'])
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/sanicms/db.py", line 142, in init
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     self._pool = await create_pool(**config, loop=self._loop, max_size=100)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 398, in _async__init__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     await self._initialize()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 415, in _initialize
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     await first_ch.connect()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 125, in connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     self._con = await self._pool._get_new_connection()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/pool.py", line 461, in _get_new_connection
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     **self._connect_kwargs)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connection.py", line 1688, in connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     max_cacheable_statement_size=max_cacheable_statement_size)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 551, in _connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     raise last_error
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 543, in _connect
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     connection_class=connection_class)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return self.gen.send(None)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/site-packages/asyncpg/connect_utils.py", line 513, in _connect_addr
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     connector, timeout=timeout, loop=loop)
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |     return fut.result()
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "uvloop/loop.pyx", line 1879, in create_connection
ms_user_server.1.2ddjhzlgwnsy@ms-node1    |   File "uvloop/loop.pyx", line 1858, in uvloop.loop.Loop.create_connection
ms_user_server.1.2ddjhzlgwnsy@ms-node1    | ConnectionRefusedError: [Errno 111] Connection refused

我查看develop 存在wait-for-it.sh 和 wait-service.sh脚本,但并未使用。不知为何?
另外,运行 eval $(docker-machine env ms-master) 后 再本地请求 http://localhost:9411/zipkin/http://localhost:8090/ 等服务接口并不能成功访问。
盼回,谢谢!

运行examples里的演示代码发现程序不能预期运行

我参照 examples 里的README.md 进行程序运行测试,发现如下错误。

Attaching to examples_swagger_1, examples_server_1, examples_db_1, examples_zipkin_1
server_1   | Traceback (most recent call last):
server_1   |   File "/usr/local/lib/python3.6/runpy.py", line 193, in _run_module_as_main
server_1   |     "__main__", mod_spec)
server_1   |   File "/usr/local/lib/python3.6/runpy.py", line 85, in _run_code
server_1   |     exec(code, run_globals)
server_1   |   File "/service/user_service/server.py", line 5, in <module>
server_1   |     from sanicms.server import app
server_1   |   File "/usr/local/lib/python3.6/site-packages/sanicms/server.py", line 29, in <module>
server_1   |     config = load_config()
server_1   |   File "/usr/local/lib/python3.6/site-packages/sanicms/__init__.py", line 9, in load_config
server_1   |     conf.from_pyfile(path)
server_1   |   File "/usr/local/lib/python3.6/site-packages/sanic/config.py", line 80, in from_pyfile
server_1   |     with open(filename) as config_file:
server_1   | FileNotFoundError: [Errno 2] Unable to load configuration file (No such file or directory): 'settings.py'

如何解决?

Client 请求持续时长问题

Client 这里,这个时候finish() ,并不真的请求时间,应该在 await res.json() 之后再finish() 吧?

def request(self, method, url, **kwargs):
        headers = self.before(method, url)
        res = self._client.request(method, self.handler_url(url),
                                   headers=headers, **kwargs)
        self._span.set_tag('component', 'http-client')
        self._span.finish()
        return res

项目是如何启动的?

查看整个sanicms项目
没发现app.run(*)
假如是用事件方式 执行 ,也没发现有这样
loop = asyncio.get_event_loop()
loop.run_until_complete(
))

请问是如何启动的?
谢谢

运行调试的一些问题

感谢作者的分享,但我在调试过程中发现一些问题,不知道是不是组件版本导致的:
1、sanicms\loggers.py
第58行data = fields.pop('args'),取出的data是tuple,导致下面data.update报错,这里我修改了一下,重新组成一个dict,原理上看这是在读取参数,因此只是给它一个独立的名字就算了。
tmp = fields.pop('args')
data = {'name': tmp[0]}

2、sanicms\server.py
也是第58行,
await service.register_service(app.config['PORT'])
而register_service有两个参数, host 和 port,这里需要加上port=app.config['PORT']

不知道这样的修改是否合适,望指教,谢谢!

NameError: name 'opentracing' is not defined

I run BUILD=y PULL=y ./develop/reset.sh,Then curl http://localhost:8000, server cannot run

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/sanic/app.py", line 538, in handle_request
    response = await self._run_request_middleware(request)
  File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)
  File "/usr/local/lib/python3.6/site-packages/sanic/app.py", line 717, in _run_request_middleware
    response = await response
  File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)
  File "/usr/local/lib/python3.6/site-packages/sanicms/server.py", line 56, in cros
    span = before_request(request)
  File "/usr/local/lib/python3.6/site-packages/sanicms/utils.py", line 124, in before_request
    span = opentracing.tracer.start_span(operation_name=handler[0].__name__,
NameError: name 'opentracing' is not defined

utils.py里文件引用问题

  1. 第108行引用了CustomException,这个CustomException是在exception里的类, 没有在utils引 用

  2. 第82至 84行,引用的是同文件里的涵数id_to_hex,为何还要加上utils.id_to_hex(x)这样的引用方式

3.第139行的tags,不在涵数before_request里,也不在全局里定义,这应该是从from opentracing.ext import tags引用的,但 utils.py没有引用

谢谢

函数命名问题

最近正在研究python微服务相关的东西,有幸接触到您的项目,还在研究
虽然这个问题很小,但是示例中 微服务的服务开始前命名错误
@app.listener('before_server_start')
async def before_srver_start(app, loop): ---> before_server_start

python版本问题

Executing busybox-1.26.2-r11.trigger
OK: 154 MiB in 51 packages
Looking in indexes: http://pypi.douban.com/simple
Collecting git+https://github.com/songcser/sanic-ms.git@master (from -r requirements.txt (line 1))
Cloning https://github.com/songcser/sanic-ms.git (to revision master) to /tmp/pip-req-build-_nq4zzoy
Collecting sanic>=0.7.0 (from sanicms==0.1->-r requirements.txt (line 1))
Downloading http://pypi.doubanio.com/packages/7b/c7/7e14ef09bcab14d1c56a4261e65a983ac72efa3fd81d109cf2120a15c793/sanic-20.12.3-py3-none-any.whl (80kB)
Collecting uvloop>=0.8.0 (from sanicms==0.1->-r requirements.txt (line 1))
Downloading http://pypi.doubanio.com/packages/94/98/9dc814f391b2293ecc790b9752e005296c69c3694fd9975b6cb77c448135/uvloop-0.15.1.tar.gz (2.1MB)
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-install-cu3x4pok/uvloop/setup.py", line 5, in
raise RuntimeError('uvloop requires Python 3.7 or greater')
RuntimeError: uvloop requires Python 3.7 or greater

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.