使用python开发的信息服务,调用他的rpc协议为可以跨语言的Thrift,
下载:http://archive.apache.org/dist/thrift/0.11.0/
然后放在这里,配置环境变量
验证安装是否成功:
然后简单的测试。验证一下thrift:
namespace是命名空间,比如我想编译成java的就写java,后面跟的是包名。然后就可以定义接口,接口以service开头,接口的名字,里面定义接口的方法。参数要指定参数的顺序和类型
然后用下面的命令生成接口文件,就是一个java类
thrift --gen
再生成一个Python的:
ok thrift安装好了就可以来进行信息服务的开发了。使用的是Python,所以先安装好Pyhon.
在一个父maven工程下,新建python工程,名字为:messgae-thrift-python-service
见一个thrift目录保存thrift的信息:
然后编写thrift:
编写shell脚本执行thrift
ok,生成接口成功:
开发发送邮件的服务:
# coding: utf-8
from message.api import MessageService
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = '[email protected]'
authCode = 'mkddaupcopvmbdjj'
class MessageServiceHandler:
def sendMobileMessage(self, mobile, message):
print "sendMobileMessage"
return True
def sendEmailMessage(self, email, message):
print ("sendEmailMessage, email:" + email + ", message:" + message)
messageObj = MIMEText(message, "plain", "utf-8")
messageObj['From'] = sender
messageObj['To'] = email
messageObj['Subject'] = Header('信息服务测试', 'utf-8')
try:
smtpObj = smtplib.SMTP('smtp.qq.com')
smtpObj.login(sender, authCode)
smtpObj.sendmail(sender, [email], messageObj.as_string())
print ("send mail success")
return True
except smtplib.SMTPException:
print ("send mail failed!")
return False
if __name__ == '__main__':
handler = MessageServiceHandler()
processor = MessageService.Processor(handler)
transport = TSocket.TServerSocket(None, "9090")
tfactory = TTransport.TFramedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print ("python thrift server start")
server.serve()
print ("python thrift server exit")
需要导入模块:
ok假设能成功。
然后java 要去调用thrift,还需要使用thrift文件去生成java的api.
pom文件:
onlinecoursesystem
com.wx
1.0-SNAPSHOT
4.0.0
message-thrift-service-api
org.apache.thrift
libthrift
0.11.0
org.apache.maven.plugins
maven-compiler-plugin
2.3.2
1.8
1.8
开发用户服务
对外提供thrift接口,用户注册成功以后需要调用信息服务发送邮件
创建一个子Model,user-thrift-service-api,定义接口,接口都是用thrift生成的。
生成接口的thrift文件:
namespace java com.wx.thrift.user
struct UserInfo {
1:i32 id,
2:string username,
3:string password,
4:string realName,
5:string mobile,
6:string email,
7:string intro,
8:i32 stars
}
service UserService {
UserInfo getUserById(1:i32 id);
UserInfo getTeacherById(1:i32 id);
UserInfo getUserByName(1:string username);
void regiserUser(1:UserInfo userInfo);
}
执行生成接口的shell之后,生成了接口和实体类:
接口创建好了以后再创建一个子模块user-thrift-service,实现上面定义的接口。接口和实现类做到了分离,分别在不同的模块之中。
接口实现的就是去与底层的数据库交互,进行增删查改,还需要开启thrift服务,等待其他服务的调用。其实可以这接使用springCloud中的fegin来调用就行了。
然后开发用户的edgeservice, 新建一个模块为user-edge-service,在这里主要就是完成单点登陆和注册的功能,并且他会对底层的服务进行调用,向外提供http接口,浏览器是可以访问的。
开发user-edge-service-client服务模块,主要是用户登陆时候的过滤,拿到token,将token存在cookie中。登陆的时候直接从token中取值。
。。。。。
服务全部开发完毕。
然后就是服务的Docker化:
首先看看user-thrift-service这个服务,Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/choerodon-tools/javabase:0.5.0
MAINTAINER xxx [email protected]
COPY target/user-thrift-service-1.0-SNAPSHOT.jar /user-service.jar
ENTRYPOINT ["java", "-jar", "/user-service.jar"]
build.sh:
#!/usr/bin/env bash
mvn clean package
docker build -t user-service:latest .
就这样就可以打出一个镜像来了。
再看看Python的信息服务,message-thrift-python-service,这个服务有对thrift的依赖,所以直接把python代码丢到python环境上是跑不起来,所以我们的解决的方式就是在python的基础基础镜像上加一个thrift模块,打成一个新的基础镜像。
先要一个Dockerfile.base文件:
FROM python:latest
MAINTAINER xxx [email protected]
RUN pip install thrift
那么在python:latest产生的容器中,如果pip install thrift这条命令不能执行怎么办?所以先要看看能不能执行。
ok可以执行
要有一个打镜像的sh文件:build_base.sh
#!/usr/bin/env bash
docker build -t python-base:latest -f Dockerfile.base .
然后执行打出镜像:
基础镜像打成功了。
然后python的服务怎么在这个基础的镜像上构建服务的镜像呢?Dockerfile:
FROM python:latest
MAINTAINER xxx [email protected]
ENV PYTHONPATH /
COPY message /message
ENTRYPOINT ["python", "/message/message_service.py"]
build.sh:
#!/usr/bin/env bash
docker build -t message-service:latest .
ok后面的服务都是这样docker化的。
docker通信:上面的过程是把服务全部docker化,现在需要把它全部连接起来通信。
自己手动开发的微服务,使用link的方式来实现通信,就是根据名字来。
而依赖的基础服务,比如redis,mysql等等,通过端口的映射来访问。
使用docker-compose来描述服务之间的关系:
version: '3'
networks:
default:
external:
name: imooc-network
services:
message-service:
image: message-service:latest
user-service:
image: user-service:latest
command:
- "--mysql.address=172.19.0.2"
user-edge-service:
image: user-edge-service:latest
links:
- user-service
- message-service
command:
- "--redis.address=172.19.0.3"
course-service:
image: course-service:latest
links:
- user-service
command:
- "--mysql.address=172.19.0.2"
- "--zookeeper.address=172.19.0.4"
course-edge-service:
image: course-edge-service:latest
links:
- user-edge-service
command:
- "--zookeeper.address=172.19.0.4"
api-gateway-zuul:
image: api-gateway-zuul:latest
links:
- course-edge-service
- user-edge-service
ports:
- 8080:8080