🦋
Butterfly 用户手册
  • Introduction
  • 一 前言
  • 二 开始
    • 安装部署
    • 五分钟体验指南
    • 单机使用手册
    • 应用规范
      • handler specs
      • middleware specs
      • xingqiao_plugin specs
      • yiqiu_program specs
  • 三 客户端功能
    • MySQL 原生协议
    • MySQL ORM
    • Redis 原生协议
      • redis_config
      • redis_tls
    • Redis ORM
    • Redis mcpack
    • Localcache
    • Kazoo
  • 四 应用(通用服务)
    • API JSON 规范
    • 异步任务 BaiChuan(百川)
    • 任务调度 RuQi(如期)
    • 任务编排 XingQiao(星桥)
    • 配置管理 WuXing(五行)
    • 运筹决策 BaiCe(百策)
  • 五 部署运维
    • 单机容器化部署
    • 监控
    • 异常排查
      • CPU Load spike every 7 hours
    • 升级
    • 安全
    • 其他
  • 六 前端
    • butterfly_template
    • butterfly_fe
    • butterfly-admin(json2web)
      • amis
      • sso
      • pangu
    • NoahV
    • PyWebIO
  • 七 潘多拉魔盒
    • 装饰器
      • localcache_decorator
      • retry_decorator
      • custom_decorator
      • command2http_decorator
    • 算法
      • 算法-分位数
      • 算法-变异系数
    • 实用工具
      • host_util
      • shell_util
      • http_util
      • time_util
      • random_util
      • concurrent
      • jsonschema
      • blinker
      • toml
      • command_util
      • config_util
      • picobox
      • 对称加密
        • des
        • aes
      • ascii_art
        • ttable
        • chart
      • business_rules
      • python-mysql-replication
      • dict_util
    • 中间件
      • middleware_status
      • middleware_whitelist
    • test_handler.py
  • 八 最佳实践
    • 分布式架构
    • Code practice
    • Log practice
    • Daemon process
  • 附录
Powered by GitBook
On this page
  • 1 特性
  • 2 架构
  • 2.1 一气化三清

一 前言

1 特性

  • 快速开发

    • (1) 多地域配置:配置支持多地域,配置可以统一管理

    • (2) 无需配置路由:根据 handlers 目录自动加载路由(目前不支持动态路由)

    • (3) 显示参数管理:Handler 的参数与 HTTP 参数保持一致,含有参数检查

    • (4) 简易调试模式:简易方便的 DEBUG

    • (5) 引擎之状态机:具有可复用性的状态处理

    • (6) 引擎之工作流:长流程分步执行,可生成 dot 流程图

    • (7) 对象关系映射:自带 ORM

    • (8) 定时任务调度:支持定时执行某些方法

  • 方便运维

    • (1) 请求完整追溯:响应 Header 中包含请求的 reqid(会记录在日志中),便于 trace

    • (2) 自定义响应头:可自定义 HTTP header,如增加固定的接口版本号

    • (3) 代码耗时打点:通过代码打点可以准确获代码执行耗时,用于排查性能问题

    • (4) 线程堆栈打印:发送 kill -10 ${pid} 触发,用于排查程序夯住问题

    • (5) 变量内存打印:发送 kill -12 ${pid} 触发,用于排查内存泄露问题

  • 容易扩展

    • (1) 消息队列通信:开启百川配置即成为消费者,以拉模式消费由其他实例发布的消息

2 架构

2.1 一气化三清

Butterfly 可以很方便将 Python 函数转换为 Http 服务,cmd,任务队列 task

    +---------------+  +-------------+  +-------------+
    |     cmd       |  |HTTP Request |  |  Queue Msg  |
    +------+--------+  +------+------+  +------^------+
           |                  |                |
  +-----------------------------------------------------+
  |        |                  |                |        |
  | +------V--------+  +------V------+  +------+------+ |
  | |test_handler.py|  |   Protocol  |  |   worker    | | Butterfly Framework
  | +------+--------+  +------+------+  +------+------+ |
  |        |                  |                |        |
  +-----------------------------------------------------+
           |                  |                |
  +--------V------------------V----------------+--------+
  |                         func                        | Application code
  +-----------------------------------------------------+


开发人员将 func code 按照 Butterfly handler 规范放在 <butterfly_project>/handlers/<app_name> package 下

要求:
    (1) 装饰器:添加 @funcattr.api 装饰器
    (2) 参数:第一个参数增加 req
    (3) 返回值:json_status, [content], [headers]
                json_status: (string) 必须有,实际返回给用户时,json_status 也会放到 json 串中,如 "OK", "ERR", "ERR_BAD_PARAMS"
                content    : (dict)非必须,API 返回结果,如 {"data": "test"}
                headers    : (list)非必须,API headers 如 [("demo", "1.0.1")]
调用:
    (1) cmd: python test_handler.py /<app_name>/<handler_name> <args>
    (2) HTTP: 启动 Butterfly 后,可以通过 curl "http://<ip>:<port>/<app_name>/<handler_name>?arg=value"
    (3) Queue: 开启百川后,自动监听对应 /<app_name>/<handler_name> 的消息

2.1.1 HTTP 请求流

       +-------------------------------------------------------------+
       |                        WEB brower                           |
       +-----------------------------------^-------------------------+
     /                      |              |
    |  +--------------------V--------------|-------------------------+
    |  | +----------------HTTPServer(Threadpool&Queue)-------------+ |
    |  | |   +-------------------+ put +-----------------------+   | |
    |  | |   |ThreadPool(Queue) <------+ HTTPConnection        |   | |
    |  | |   |+---------------+  |     | +-------------------+ |   | |
    |  | |   ||WorkerThread   |  |     | |req=HTTPRequest()  | |   | |
    |  | |   ||+-+ +-+ +-+ +-+|  |     | |req.parse_request()| |   | |(把 socket 字节流,按 HTTP 协议解析)
    |  | |   ||+-+ +-+ +-+ +-+|  |     | |req.respond()#^!^  | |   | |(封装了 WSGIGateway.response)
    |  | |   |+-|---|---|---|-+  |     | +-------------------+ |   | |
    |  | |   +--|---|---|---|----+     +-----------------------+   | |
    |  | +------|---|---|---|-----------------------^--------------+ |
    |  |        |   |   |   |                       |                | WSGI server
    |  | +------V---V---V---V-WSGIGateway(response)-|--------------+ |
    |  | |                       +------------------+-------------+| |
    |  | |+----------------+     | +----------+   +-------------+ || |
    |  | ||   gen environ  |     | |header_set|   |response body| || |
    |  | |+-----+----------+     | +----------+   +-------------+ || |
    |  | |      |                +--^------^----------^-----------+| |
    |  | +------|-------------------|------|----------|------------+ |
    |  +--------|-------------------|------|----------|--------------+
    |  .........|...................|......|..........|......................
    |           |                   |      |          |
    |  +--------V--------+          |      |          |
    |  |       req       |          |      |          |        (1) 封装 environ 为 Request
    |  +-----------------+          |      |          |            生成 reqid
Butterfly       |                   |      |          |
    |           |                   |      |          |      \
    |  +--------V--------+          |      |          |       |(2) 路由
    |  |  apiname_getter |          |      |          |       |    在路由字典中匹配 environ['PATH_INFO']
    |  +-----------------+          |      |          |       |    {
    |           |                   |      |          |       |      '/apidemo/ping':
    |           |                   |      |          |       |        <xlib.protocol_json.Protocol object>,
    |  +--------V--------+ False +--+--+   |          |       |      '/{app}/{handler}':
    |  |is_protocol_exist|------>| 400 |   |          |       |        <xlib.protocol_json.Protocol object>
    |  +-----------------+       +-----+   |          |       |    }
    |           |                          |          |      /
    |  .........|..........................|..........|......................
    |           | (protocol_process)       |          |      \
    |           V                          |          |       |(3) 返回 Response
    |  +-----------------+                 |          |       |    参数:第一个参数为 Request 实例化对象 req
    |  | protocol        | Exception    +-----+       |       |          其他参数为 GET 请求参数名
    |  | +-------------+ |------------->| 500 |       |       |    例子:environ['QUERY_STRING']: 'age=16'
    |  | |/app1/handler| |              +-----+       |       |    +-------------handler demo---------------
    |  | |/app2/handler| |Normal+----------------------------+|    |@funcattr.api      # 标识 handler 类型
    |  | +--+-------+--+ |----->|httpstatus, headers, content||    |def demo(req, age):# req + HTTP 请求参数
    |  +----|-------|----+      +----------------------------+|    |   #(状态信息,数据信息,响应头列表)
    |       |       |                                         |    |   return "OK", {"data": age}, []
    |       |       |                                        /     +----------------------------------------
    |       |  +----V----------------------------------+
    |       |  |+---------+  +---------+  +-----------+|
    |       |  ||DiskCache|  |   FSM   |  |APScheduler||       基础公共库
    |       |  |+---------+  +---------+  +-----------+|
    |       |  +---------------------------------------+
    |  +----V------------------------------------------+
    |  |       (Redis ORM) / (MySQL ORM) / RAL         |       数据访问层
     \ +-----------------------------------------------+

2.1.2 Queue msg

+-----------------+
| register worker | 注册 worker
+-------+---------+
        |
+-------V---------+
|check_task_status| 检查任务的状态
+-------+---------+
        |
+-------V---------+
|queue.dequeue_any| 随机从多个队列中获取消息
+-----------------+
        |
+-------V-----------------+
|msg.set_status("started")| 设置消息状态
+-------+-----------------+
        |
+-------V---------+
|   pool.submit   | 提交到多线程队列中
+-----------------+
PreviousIntroductionNext二 开始

Last updated 9 months ago