zoukankan      html  css  js  c++  java
  • 一、配置服务器,项目初始化,RPC接口

    服务器系统:centos7.6.1810

    1. 安装软件

    1.1 git

    yum install git

    1.2 mysql

    安装命令

    yum install mysql-server

    提示未找到,则需要添加yum源,将从官网下载的mysql-community.repo放入/etc/yum.repos.

    1.3 虚拟环境

    安装virtualenv和virtualenvwrapper

    配置

    ...

    创建虚拟环境

    2. 创建项目,码云建立仓库并上传

    创建项目

    cd /root
    mkdir moguapp
    cd moguapp
    # 创建flask项目启动文件manage.py
    vim manage.py

    创建项目启动文件manage.py

    并写入代码:

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
      return 'hello here is index html'
    
    
    if __name__ == '__main__':
      app.run(host='0.0.0.0', port=5000) 

    在终端下使用python manage.py运行测试服务器

    python manage.py

    浏览器访问结果

     到码云创建仓库,代码上传到码云

    在/root/moguapp/下进行以下步骤

    git config --global user.name "yijue_lu"
    git config --global user.email "2117578083@qq.com"
    git init
    git add .
    git commit -m "创建manage.py文件,写入基本代码,并成功运行"
    git remote add origin https://gitee.com/yijue_lu/mogu.git
    git push -u origin master

     码云结果

     

     3. 项目初始化

    3.1 目录结构

     建立如下目录结构

    moguapp/
    ├─ logs/                   # 日志文件存储目录
    ├─ apps/                   # 项目主要逻辑业务代码保存目录
    │  ├─ __init__.py          # 项目初始化文件
    │  ├─ modules/             # 保存项目中所有api模块的存储目录
    │  │  ├─ common/           # 公共api接口目录
    │  │  │  ├─ __init__.py    # 公共api接口的初始化文件
    │  │  │  ├─ models.py      # 公共api接口的模型文件
    │  │  │  └─ api.py         # 公共api接口代码文件
    │  │  └─ __init__.py
    |  ├─ utils/               # 项目自定义封装工具包目录
    |  ├─ libs/                # 项目第三方工具包目录
    |  ├─ settings/            # 项目配置存储目录
    │  │  ├─ dev.py            # 开发阶段的配置文件
    │  │  ├─ prop.py           # 生产阶段的配置文件
    │  │  └─ __init__.py
    │  └─ statics/             # 保存项目中所有的静态资源文件[img/css/js]
    └── manage.py              # 项目的终端管理脚本文件

    3.2 写入配置信息

    写入基本配置信息

    到moguapp/apps/settings/__init__.py

    import redis
    class Config(object):
        """项目配置信息"""
        # 设置密钥,可以通过 base64.b64encode(os.urandom(48)) 来生成一个指定长度的随机字符串
        SECRET_KEY = "T1vEjTCjkGon5vU8C6Xq3ujNSQgHQje"
        # 配置日志
        LOG_LEVEL = "DEBUG"
    
        # 调试模式
        DEBUG = True
    
        # 数据库的配置信息
        SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/mogu?charset=utf8"
        SQLALCHEMY_TRACK_MODIFICATIONS = True
        SQLALCHEMY_ECHO = True
    
        # redis配置
        REDIS_HOST = "127.0.0.1"
        REDIS_PORT = 6379
    
        # session 配置
        SESSION_TYPE = "redis"  # 指定 session 保存到 redis 中
        SESSION_USE_SIGNER = True  # session_id 进行加密签名处理
        SESSION_REDIS = redis.StrictRedis( host=REDIS_HOST, port=REDIS_PORT,db=1 )
        PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,单位是秒

     写入开发环境配置信息

    到moguapp/apps/settings/dev.py

    from . import Config
    class DevelopementConfig(Config):
      """开发模式下的配置"""
      pass

     写入生产环境配置信息

    到moguapp/apps/settings/prop.py

    from . import Config
    class ProductionConfig(Config):
        """生产模式下的配置"""
        DEBUG = False
        LOG_LEVEL = "INFO"
        SQLALCHEMY_TRACK_MODIFICATIONS = False
        SQLALCHEMY_ECHO = False

    3.3 配置项目日志

    把日志配置封装在init_log函数中,保存到utils/log.py文件

    import logging
    from logging.handlers import RotatingFileHandler
    
    # 把日志相关的配置封装成一个日志初始化函数
    def init_log(Config):
        # 设置日志的记录等级
        logging.basicConfig(level=Config.LOG_LEVEL)  # 调试debug级
        # 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
        file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 300, backupCount=10)
        # 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
        formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
        # 为刚创建的日志记录器设置日志记录格式
        file_log_handler.setFormatter(formatter)
        # 为全局的日志工具对象(flaskapp使用的)添加日志记录器
        logging.getLogger().addHandler(file_log_handler)

    3.4 项目初始化代码抽取

    在apps/__init__.py文件中,创建flask应用并加载配置

    from flask import Flask
    from redis import StrictRedis
    from flask_session import Session
    from flask_sqlalchemy import SQLAlchemy
    
    from apps.settings.dev import DevelopementConfig
    from apps.settings.prop import ProductionConfig
    from apps.utils.log import init_log
    
    config = {
        "dev": DevelopementConfig,
        "prop": ProductionConfig,
    }
    
    # 预设全局变量
    redis_store = None
    db = SQLAlchemy()
    
    def init_app(config_name):
        """项目的初始化功能"""
        app = Flask(__name__)
    
        # 设置配置类
        Config = config[config_name]
    
        # 加载配置
        app.config.from_object(Config)
    
        # redis的链接初始化
        global redis_store
        redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT,db=0)
    
        # 开启session功能
        Session(app)
        
        # 配置数据库链接
        db.init_app(app)
    
        # 启动日志
        init_log(Config)
    
        return app

    3.5 配置项目启动文件

    修改manage.py启动文件,加载app初始化工厂函数(from apps import init_app),并使用flask-script启动项目

    #from flask import Flask
    
    from flask_script import Manager
    from flask_migrate import Migrate, MigrateCommand
    
    from apps import init_app,db
    
    #app = Flask(__name__)
    app = init_app("dev")
    
    # 使用终端脚本工具启动和管理flask
    manager = Manager(app)
    
    # 启用数据迁移工具
    Migrate(app, db)
    # 添加数据迁移的命令到终端脚本工具中
    manager.add_command('db', MigrateCommand)
    
    @app.route('/')
    def index():
      return 'hello,moluo~'
    
    if __name__ == '__main__':
        #app.run(host=0.0.0.0, port=5000)
        manager.run()

    在终端重新使用manage.py启动项目

    python manage.py runserver --host=0.0.0.0 --port=5000

    4. 基于Flask-JSONRPC提供RPC接口

    JSON-RPC是一个无状态的、轻量级的远程过程调用(RPC)协议。

    所谓的RPC,Remote Procedure Call的简写,中文译作远程过程调用或者远程服务调用。

    直观的理解就是,通过网络来请求服务,获取接口数据,而不用知晓底层网络协议的细节。

    RPC支持的格式很多,比如XML格式,JSON格式等等。最常用的肯定是json-rpc。

    JSON-RPC协议中的客户端一般是为了向远程服务器请求执行某个方法/函数。客户端向实现了JSON-RPC协议的服务端发送请求,多个输入参数能够通过数组或者对象传递到远程方法,这个远程方法也能返回多个输出数据,具体是什么,当然要看具体的方法实现。

    所有的传输都是单个对象,用JSON格式进行序列化。

    请求要求包含三个特定属性:

    jsonrpc: 用来声明JSON-RPC协议的版本,现在基本固定为“2.0”
    
    method,方法,是等待调用的远程方法名,字符串类型
    
    params,参数,对象类型或者是数组,向远程方法传递的多个参数值
    
    id,任意类型值,用于和最后的响应进行匹配,也就是这里设定多少,后面响应里这个值也设定为相同的
    响应的接收者必须能够给出所有请求以正确的响应。这个值一般不能为Null,且为数字时不能有小数。

    响应也有三个属性:

    result,结果,是方法的返回值,调用方法出现错误时,必须不包含该成员。
    
    error,错误,当出现错误时,返回一个特定的错误编码,如果没有错误产生,必须不包含该成员。
    
    id,就是请求带的那个id值,必须与请求对象中的id成员的值相同。请求对象中的id时发生错误(如:转换错误或无效的请求),它必须为Null

    当然,有一些场景下,是不用返回值的,比如只对客户端进行通知,由于不用对请求的id进行匹配,所以这个id就是不必要的,置空或者直接不要了。

    在flask中要实现提供json-rpc接口,开发中一般使用Flask JSON-RPC模块来实现。

    git地址:https://github.com/cenobites/flask-jsonrpc

    文档:http://wiki.geekdream.com/Specification/json-rpc_2.0.html

    4.1 安装Flask-JSONRPC模块

    pip install Flask-JSONRPC==0.3.1

    快速实现一个测试的RPC接口。

    在manage.py启动文件中

    添加jsonrpc相关代码

    实现:

    from flask_script import Manager
    from flask_migrate import Migrate, MigrateCommand
    from flask_jsonrpc import JSONRPC
    
    from apps import init_app, db
    
    
    #app = Flask(__name__)
    
    app = init_app('dev')
    
    # 使用终端脚本工具启动和管理flask
    manager = Manager(app)
    
    # 启用数据迁移工具
    Migrate(app, db)
    
    # 添加数据迁移命令到终端脚本工具中
    manager.add_command('db', MigrateCommand)
    
    # 初始化jsonrpc模块
    jsonrpc = JSONRPC(app, '/api')
    
    # 实现jsonrpc接口
    @jsonrpc.method('Common.index') # 此行index跟下一行index不是同一个,下一行index可以改为其他
    def index():
      return 'jsonrpc export'
    
    @app.route('/')def index():
      #return 'hello here is index html'
      return 'init succese'
    
    
    if __name__ == '__main__':
      #app.run(host='0.0.0.0', port=5000)
      manager.run()

     问题:Common.index未理解!

    注意:客户端需要发起post请求,访问地址为:http://服务器地址:端口/api

    注意默认情况下,/api接口只能通过post请求访问。如果要使用jsonrpc提供的界面调试工具,则访问地址为:

    http://服务器地址端口/api/browse/

     

    访问数据格式应是:

    {
        "jsonrpc": "2.0",
        "method": "Comon.index",
        "params": {},
        "id": "1"
    }

     使用postman发送post请求进行测试

    效果如下:

    4.2 对RPC接口代码进行模块化分离

    把jsonrpc模块的初始化代码抽离到app对象初始化函数init__app中。

    apps/__init__py,代码:

    添加以下代码

    ...
    from flask_jsonrpc import JSONRPC
    
    ...
    #创建jsonrpc实例对象
    jsonrpc = JSONRPC(app=None, service_url='/api', enable_web_browsable_api=True)
    ...
    
    def init_app(config_name):
        ...
        # jsonrpc注册到app应用对象中
        jsonrpc.init_app(app)
        ...

    modules/common/api.py,代码:

    from apps import jsonrpc
    # 实现rpc接口
    @jsonrpc.method('Common.index')
    def index():
        return u'Welcome to Flask JSON-RPC' #有中文要加 u

    manage.py启动文件中注释掉jsonrpc部分代码并增加api接口:

    #from flask import Flask
    
    from flask_script import Manager
    from flask_migrate import Migrate, MigrateCommand
    #from flask_jsonrpc import JSONRPC
    
    from apps import init_app, db
    
    
    #app = Flask(__name__)
    
    app = init_app('dev')
    
    # 使用终端脚本工具启动和管理flask
    manager = Manager(app)
    
    # 启用数据迁移工具
    Migrate(app, db)
    
    # 添加数据迁移命令到终端脚本工具中
    manager.add_command('db', MigrateCommand)
    
    ## 初始化jsonrpc模块
    #jsonrpc = JSONRPC(app, '/api')
    
    ## 实现jsonrpc接口
    #@jsonrpc.method('Common.index')
    #def index():
    #  return 'jsonrpc export'
    
    # api接口列表
    from apps.modules.common import api
    
    @app.route('/')
    def index():
      #return 'hello here is index html'
      return 'init succese'
    
    
    if __name__ == '__main__':
      #app.run(host='0.0.0.0', port=5000)
      manager.run()

     重新启动项目,使用postman进行还是原来的结果,则表示调整成功,后面的开发中,我们只需要不断增加对应的接口即可。

    4.3 使用jsonrpc接受客户端请求的参数

     服务器提供rpc接口方法:

    from apps import jsonrpc
    
    @jsonrpc.method("模块名.方法名(username=String, password=String)")
    def 方法名(username,password):
        return u"账号:%s,密码:%s" % (username,password)

     modules/common/api.py添加rpc接口(add方法)

    问题:如果添加两个都是Common.index ?

    尝试结果:会覆盖上一个

    from apps import jsonrpc
    # 实现rpc接口
    @jsonrpc.method('Common.index')
    def index():
        return u'Welcome to Flask JSON-RPC'
    
    @jsonrpc.method('Common.add(name=String,sex=String)')
    def index1(name,sex):
        return 'name %s, sex %s'%(name,sex)

    postman发送请求内容:

    {
        "jsonrpc": "2.0",
        "method": "Common.add",
        "params": {
            "name": "xiaoming",
            "sex": "man"
        },
        "id": "1"
    }

    效果:

     

    注意:数据类型要对应

     4.4 实现jsonrpc接口的版本迭代

    基于flask_jsonrpc.site.JSONRPCSite 来实现

    apps/__init__.py添加代码:

    from flask_jsonrpc.site import JSONRPCSite
    ...
    
    #jsonrpc接口版本迭代
    
    jsonrpc_v2 = JSONRPC(app=None, service_url='/api/v2',site=JSONRPCSite(), enable_web_browsable_api=True)
    
    def init_app(config_name):
        ...
      # jsonrpc注册到app应用对象中 jsonrpc_v2.init_app(app)

     modules/common/api.py添加代码:

    from apps import jsonrpc, jsonrpc_v2
    
    @jsonrpc_v2.method('Common.add(name=String,sex=String)')
    def index(name,sex):
        return 'v2:(name %s, sex %s)'%(name,sex)

    效果:

     

     尝试:不使用JSONRPCSite进行版本迭代,发现会覆盖之前的jsonrpc对象,访问时报错,没有url

     

    尝试
    
    
    /root/moguapp/apps/__init__.py下添加
    ...
    jsonrpc_test = JSONRPC(app=None, service_url='/api/test',enable_web_browsable_api=True)
    ...
    def init_app(config_name):
    ...
    jsonrpc_test.init_app(app)
    ...
    
    
    /root/moguapp/apps/modules/common/api.py下添加
    
    from apps import jsonrpc, jsonrpc_test
    
    @jsonrpc_test.method('Common.add(name=String,sex=String)')
    def index(name,sex):
        return 'test:(name %s, sex %s)'%(name,sex)
  • 相关阅读:
    VUE处理项目中的ESLint语法报错问题
    通过Focas连接Fanuc的NC Guide
    IdentityServer
    Dapper2.0.78手册翻译
    Framework项目持续集成(jenkins)及集合SonarQube
    基于 GitBook 搭建个人博客
    GitBook 常用插件
    Vue管理系统前端系列六动态路由-权限管理实现
    Vue管理系统前端系列五自定义主题
    Vue管理系统前端系列四组件拆分封装
  • 原文地址:https://www.cnblogs.com/yijue-lu/p/10968194.html
Copyright © 2011-2022 走看看