|
- # -*- coding: utf-8 -*-
- import os
- import yaml
- import socket
- import logging
- import tornado.web
- import tornado.ioloop
- import tornado.websocket
- import tornado.httpserver
- from tornado.httputil import HTTPHeaders
- from app.global_data.global_data import g
- from app.service import ability_service
-
-
- class GatewayApi(tornado.web.RequestHandler):
-
- async def get(self, *args, **kwargs):
- g.current_connections += 1
- if g.current_connections > g.config.max_connections:
- g.current_connections -= 1
- self.set_status(500)
- self.write('API网关限流,服务暂不可用!')
- return
-
- try:
- response = await ability_service.forward_request(self.request)
-
- self.set_status(response.code)
- self._headers = HTTPHeaders(response.headers) # 注意:需要强制类型转换
-
- if self._headers.get('Content-Type') == 'gzip':
- try:
- self._headers.pop('Content-Type')
- self._headers.pop('Content-Length')
- except:
- pass
-
- if self._headers.get('Transfer-Encoding'):
- self._headers.pop('Transfer-Encoding')
-
- if self._headers.get('Content-Length') is not None:
- self.set_header('Content-Length', len(response.body))
-
- if self.request.headers.get('Origin'):
- self.set_header('Access-Control-Allow-Credentials', 'true')
- self.set_header('Access-Control-Allow-Origin', self.request.headers.get('Origin'))
-
- if self._status_code in (204, 304) or 100 <= self._status_code < 200:
- # 这些状态下response中不能有body,所以不应该write
- return
-
- self.write(response.body)
- except Exception as e:
- logging.error(str(e))
- self.set_status(500)
- self.write('模型微服务无法访问!')
-
- g.current_connections -= 1
-
- async def post(self, *args, **kwargs):
- g.current_connections += 1
- if g.current_connections > g.config.max_connections:
- g.current_connections -= 1
- self.set_status(500)
- self.write('API网关限流,服务暂不可用!')
- return
-
- try:
- response = await ability_service.forward_request(self.request)
-
- self.set_status(response.code)
- self._headers = HTTPHeaders(response.headers) # 注意:需要强制类型转换
-
- if self._headers.get('Content-Type') == 'gzip':
- try:
- self._headers.pop('Content-Type')
- self._headers.pop('Content-Length')
- except:
- pass
-
- if self._headers.get('Transfer-Encoding'):
- self._headers.pop('Transfer-Encoding')
-
- if self._headers.get('Content-Length') is not None:
- self.set_header('Content-Length', len(response.body))
-
- if self.request.headers.get('Origin'):
- self.set_header('Access-Control-Allow-Credentials', 'true')
- self.set_header('Access-Control-Allow-Origin', self.request.headers.get('Origin'))
-
- if self._status_code in (204, 304) or 100 <= self._status_code < 200:
- # 这些状态下response中不能有body,所以不应该write
- return
-
- self.write(response.body)
- except Exception as e:
- logging.error(str(e))
- self.set_status(500)
- self.write('模型微服务无法访问!')
-
- g.current_connections -= 1
-
- async def options(self, *args, **kwargs):
- # 允许跨域
- self.set_status(204)
- self.set_header('Access-Control-Allow-Credentials', 'true')
- self.set_header('Access-Control-Allow-Origin', self.request.headers.get('Origin'))
- self.set_header("Access-Control-Allow-Headers", "content-type")
- self.set_header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
-
-
- class HealthChecker(tornado.web.RequestHandler):
- async def get(self, *args, **kwargs):
- self.write('{"description": "Micro-service Discovery Client", "status": "UP"}')
-
-
- def get_local_ip():
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- try:
- s.connect(('8.8.8.8', 80))
- ip = s.getsockname()[0]
- finally:
- s.close()
-
- return ip
-
-
- def start():
- app_profile = os.environ.get('APP_PROFILE', 'dev').lower()
- log_level = logging.DEBUG if app_profile == 'dev' else logging.ERROR
- logging.basicConfig(level=log_level, format='%(asctime)s - %(levelname)s - %(message)s')
-
- try:
- with open('./application.yml', 'rb') as f:
- yml = yaml.load(f, Loader=yaml.SafeLoader)
- except:
- logging.error('服务配置文件application.yml不存在!')
- return
-
- try:
- ename = yml['service']['ename']
- except:
- logging.error('未指定服务英文名!请在application.yml文件中编辑修改...')
- return
-
- try:
- cname = yml['service']['cname']
- except:
- cname = ename.upper()
-
- if app_profile == 'dev':
- try:
- port = yml['service']['port']['dev']
- except:
- logging.error('未指定服务端口号!缺省使用80端口。')
- port = 80
- else:
- try:
- port = yml['service']['port']['prod']
- except:
- logging.error('未指定服务端口号!缺省使用80端口。')
- port = 80
-
- g.load_global_data()
- if not g.init_success:
- logging.error('微服务: {}/{} 初始化加载global_data失败!'.format(cname, ename))
- return
-
- handlers = [
- (r'/management/health', HealthChecker),
- (r'/(.*)', GatewayApi),
- ]
-
- debug = 'dev' == app_profile # 开发模式缺省启动debug
-
- app = tornado.web.Application(
- handlers=handlers,
- debug=debug
- )
- http_server = tornado.httpserver.HTTPServer(app, max_buffer_size=1000 * 1024 * 1024)
- http_server.bind(port)
- http_server.start(num_processes=1)
-
- logging.critical('##################################################')
- logging.critical(' 微服务: {}/{} started ...'.format(cname, ename))
- logging.critical(' Listening at: {}:{}'.format(get_local_ip(), port))
- logging.critical(' App profile: {}'.format(app_profile))
- logging.critical('##################################################')
- tornado.ioloop.IOLoop.current().start()
-
-
- if __name__ == '__main__':
- start()
|