1、配置服務器,項目初始化,RPC接口

 

 

服務器系統:centos7.6.1810css

1. 安裝軟件

 

1.1 githtml

yum install git

 

1.2 mysqlpython

 

安裝命令mysql

yum install mysql-server

提示未找到,則須要添加yum源,將從官網下載的mysql-community.repo放入/etc/yum.repos.git

 

1.3 虛擬環境github

安裝virtualenv和virtualenvwrapperweb

配置redis

...sql

建立虛擬環境數據庫

 

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)
相關文章
相關標籤/搜索