基于wsgi协议的web服务组合方法
1.什么是wsgi?
Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是Python应用程序或框架和Web服务器之间的一种接口,已经被广泛接受, 它已基本达成它了可移植性方面的目标。
WSGI 没有官方的实现, 因为WSGI更像一个协议. 只要遵照这些协议,WSGI应用(Application)都可以在任何服务器(Server)上运行, 反之亦然。
2.如何实现WSGI?
首先我们引入一个wsgi提供的类,在wsgi协议中被称之为容器,代码如下:
import re
class Dispatcher(object): #做调度函数使用
def __init__(self, handle404 = None):
self.urls = dict()
self.request_path = ''
if handle404:
self.handle404 = handle404
else:
self.handle404 = self._404
def __call__(self, environ, start_response): #配置响应函数
self.request_path = environ.get('PATH_INFO', '')
for url in self.urls:
regex = re.compile(url)
if regex.match(self.request_path):
m = regex.match(self.request_path)
mod_name, func_name = self._get_mod_func(self.urls[url])
try:
callback = getattr(__import__(mod_name, {}, {}, ['']), func_name)
except ImportError, e:
raise Exception, "Could not import %s. Error was: %s" % (mod_name, str(e))
except AttributeError, e:
raise Exception, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))
args = (environ, start_response)
kwargs = dict()
for i in regex.groupindex:
kwargs[i] = m.group(i)
# data
return callback(*args, **kwargs)
# No match with the defined urls
return self.handle404(environ, start_response)
def _get_mod_func(self, callback):
"""
Converts 'path.to.module.funtion' to ['path.to.module', 'function']
"""
try:
d = callback.rindex('.')
except ValueError:
return callback, ''
return callback[:d], callback[d+1:]
def _404(self, environ, start_response): #找寻不到服务报错函数
start_response("404 Not Found", [('content-type', 'text/html')])
return ['Not Found']
def add(self, regex, handler):
self.urls[regex] = handler
将以上代码写入Python文件,并命名为dispatcher.py。
在服务器上运行该文件即可。
此时我们需要一个程序来使用这个Wsgi类,创建名为views.py的文件,并将一下代码写入该文件:
#!usr/bin/env python
import urllib
import os
import commands
import sys
import cgi
from cgi import parse_qs, escape
from wsgiref.simple_server import make_server
def app01(environ, start_response):#第一个服务
start_response("200 Ok", [('content-type', 'text/html')])
start_response(status, response_headers)
try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0
print '!'
#print request_body_size
request_body = environ['wsgi.input'].read(request_body_size)
d = request_body
#print type(d)
b=parse_qs(d)
#print d
A=b['x1'][0]
#print A
#return b['x1']
a=commands.getoutput('python /home/Cloud02/use/App01 linkmysql.py '+A)
return a
def app02(environ, start_response):
start_response("200 Ok", [('content-type', 'text/html')])
#result1=commands.getoutput('python application1.py')#此处可调用系统命令运行环境下的所有执行文件
return ['1234567890']
def app04(environ, start_response):
print "using IMT", app.current_imt
start_response('200 OK', [('Content-Type', app.current_imt)])
app.current_imt, app.other_imt = app.other_imt, app.current_imt
return [HTML]
完成后保存在和上一个文件同一目录下即可。
接着创建名为urls.py的文件,写入一下代码:
from dispatcher import Dispatcher
dispatcher = Dispatcher()#使用调度函数
dispatcher.add(r'^/app01/$', 'views.app01')#服务文件所在的根目录
dispatcher.add(r'^/app02/$', 'views.app02')
dispatcher.add(r'^/app03/$', 'views.app03')
dispatcher.add(r'^/app04/$', 'views.app04')
dispatcher.add(r'^/app05/$', 'views.app05')
HOST = '192.168.60.117'#服务器ip地址
PORT = 8080#服务器端口号
if __name__ == "__main__": #运行服务器
from wsgiref.simple_server import make_server
server = make_server(HOST, PORT, dispatcher)
print 'Starting up HTTP server on port %i..........' % PORT
server.serve_forever()
保存在和之前两个文件同一目录下即可。
以上便实现了Wsgi协议。
3.如何进行服务组合?
此时我们有一个服务文件,作为第一个被调用的服务,命名为test1.py。代码如下:
import urllib2
import urllib
import os
import commands
import sys
import cgi
from cgi import parse_qs, escape
from wsgiref.simple_server import make_server
from sc import Mysql
print '<center><h1>This is 192.168.1.139 !</h1></center>'
b = commands.getoutput('./a.out 2>/dev/null') #this is a test,do not print the error!,使用系统命令crul调用服务
print b
mysql = Mysql()
mysql.connect('localhost','root','mysql','scdb')
nextsid = mysql.get_nsid(1001)
temp1 = ",".join(nextsid)
print 'The next service ID: '
print temp1 + '<br>'
temp2 = int(temp1)
nexturl = mysql.get_nsurl(temp2)
temp3 = ",".join(nexturl)
print 'The next service url:'
print temp3 + '<br>' #str
a = commands.getoutput('curl ' + temp3+ ' 2>/dev/null') #both
print a
将文件存入/home/Service/Serivce下。
完成后进入与之联网的服务器2号下,同样如上部署Wsgi协议,完成后在/home/Service/Service目录下创建名为test2.py的文件。
将代码写入该文件,代码如下:
import urllib2
import urllib
import os
import commands
import sys
import cgi
from cgi import parse_qs, escape
from wsgiref.simple_server import make_server
print '<HR style="FILTER: alpha(opacity=100,finishopacity=0,style=2)" width="80%" color=#987cb9 SIZE=10>'
print '<center><h1>This is 192.168.1.143 !</h1></center>'
for line in open('/home/Service/Service/webpage.txt'):
print line
保存文件即可,注意,此处我们使用程序打开一个html文件,目的是在远端看到网页。
4.效果示范
分别在两个服务器上运行urls.py这个文件,返回值为端口号,
注意:端口号可以自己设定。
此时打开浏览器,在地址栏输入192.168.1.139:8080/app05/,得到一下界面:
此时服务组合调用成功。