本文将指引你创建一个整合了3个外部应用的简单的服务,经过HTTP和ZeroMQ来传输,经过JSON和XML来交换数据html
服务是什么?
服务是一个功能,至关于一个函数或方法,但服务运行的层次更高,函数和方法是代码层面的接口(使用APIs时通常是引入一些代码),而服务是系统层面的(经过网络协议如HTTP访问)前端
一个原子的和可重用的服务可用于构建一个在线的中间件和后端应用web
服务经过一些协议被调用或接受链接,如: plain HTTP, SOAP, JSON, AMQP, JMS WebSphere MQ, ZeroMQ, SQL, and FTP(S).redis
Zato结合Redis提供了一个用于执行周期性任务的计划任务管理器sql
服务在安全认证方面使用 HTTP Basic Auth, WS-Security 和 technical accounts.数据库
你能够经过命令行界面,API和Web admin面板来管理Zatojson
咱们将完成下面几件事:ubuntu
在教程结束时你能很好的了解Zato的特性,如:命令行接口,Web管理界面,热部署,统计等。后端
虽然这些只是Zato中的不多一部分知识,可是会给你一个完整的概念浏览器
咱们从一个最简单银行应用开始:
上图中Service和Redis颜色同样,是由于他们都在Zato集群中,而其它的不属于Zato
客户端应用(Client App)是什么咱们不讨论,它能够用不少前端技术实现,本文中的客户端用Curl来模拟
开始以前,你须要安装好了Redis和PostgreSQL,这两样东西是外部组件,没有打包到Zato里面,因此你要单独安装。你也可使用Oracle替换PostgreSQL,这里咱们仍是使用PostgreSQL。
ubuntu下能够简单的使用apt-get install redis-server
和apt-get install postgresql
来安装
Redis不须要用户,Postgres须要用下面的命令配置一下
$ sudo su - postgres # OS X users may skip it
$ createuser --no-superuser --no-createdb --no-createrole zato1
$ createdb --owner=zato1 zato1
$ psql --dbname zato1 --command="ALTER ROLE zato1 WITH PASSWORD 'zato1'"
接下来咱们快速创建一个学习用的集群,先作些准备:
* 一个空目录($path
)
* PostgreSQL的IP,端口,数据库和帐号密码($odb_host, $odb_port, $odb_db_name, $odb_user and $odb_password
)
* 用于链接Redis的IP,端口,密码($kvdb_host, $kvdb_port and $kvdb_password
)
好了,如今能够运行下面的命令,代入上面准备好的参数
注意Redis密码默认为空
$ zato quickstart create $path \
postgresql $odb_host $odb_port $odb_user $odb_db_name \
$kvdb_host $kvdb_port --verbose
代入后运行:
$ zato quickstart create ~/tmp/qs-1/ \ postgresql localhost 5432 zato1 zato1 \ localhost 6379 --verbose ODB database password (will not be echoed): Enter the odb_password again (will not be echoed): Key/value database password (will not be echoed): Enter the kvdb_password again (will not be echoed): [1/8] Certificate authority created [2/8] ODB schema created [3/8] ODB initial data created [4/8] server1 created [5/8] server2 created [6/8] Load-balancer created Superuser created successfully. [7/8] Web admin created [8/8] Management scripts created Quickstart cluster quickstart-34657 created Web admin user:[admin], password:[esou-kozo-unda-snon] Start the cluster by issuing the /home/dsuch/tmp/qs-1/zato-qs-start.sh command Visit https://zato.io/support for more information and support options $
注意到Web admin user:[admin], password:[esou-kozo-unda-snon]
没,这个帐号密码用于登陆刚创建的web admin系统,密码是个随机的密码,你能够用zato update password命令修改
看看咱们用zato quickstart create
生成了哪些东西:
到这里,咱们经过命令搭建了一个完整的环境
后面咱们会使用的一些重要TCP端口以下:
Port | 说明 |
---|---|
11223 | 负载均衡使用的HTTP端口(外面应用经过它调用你开发的服务) |
17010 | server1的HTTP端口 |
17011 | server2的HTTP端口 |
8183 | web admin的HTTP端口(在浏览器中用admin用户登陆) |
负载均衡和servers能够运行在不一样的主机上,本教程中把这些都放在了本机中.
虽然这只是个教程,但真实环境中一样能够这样作,到时只将’server1’需改名为’dev1’,而后手动增长和配置更多的’server’
此刻,你须要确认Redis和PostgreSQL都正常而且容许Zato链接,你能经过下面的命令检测:
$ zato check-config /path/to/server1 SQL ODB connection OK Redis connection OK $
若是你的输出和上面不同,则下面的./zato-qs-start.sh
会失败,因此请务必确认一下.
好了,咱们运行zato-qs-start.sh
把Zato跑起来:
$ ./zato-qs-start.sh Starting the Zato quickstart environment Running sanity checks [1/6] Redis connection OK [2/6] SQL ODB connection OK [3/6] Load-balancer started [4/6] server1 started [5/6] server2 started [6/6] Web admin started Zato quickstart environment started Visit https://zato.io/support for more information and support options $
Zato内置了一些有用的功能,其中一个是zato.ping
,它会在Zato启动时自动加载,你可使用Curl访问它(下面的输出稍微格式化了下)
$ curl localhost:11223/zato/ping -d '{}' {"zato_env": {"details": "", "result": "ZATO_OK", "cid": "K215495307960446051245422023713428938487"}, "zato_ping_response": {"pong": "zato"}} $
zato.ping
的响应是JSON格式.
开启你最爱的IDE来创建咱们的第一个Zato服务
保存下面的代码到my_service.py文件
from zato.server.service import Service class GetClientDetails(Service): def handle(self): self.log_input()
zato.server.service.Service
的子类handle(self)
是服务须要实现的惟一的方法,是服务的核心log_input
是服务能够访问的一个helper方法,你能想像,log_input会输出全部的输入数据到server日志中代码保存好了,咱们如今就能够热部署它.
说到这里,咱们有几种方法使代码生效,热部署是其中一种
经过命令行或web admin面板,你将一个服务推送到集群中一个服务器,Zato将自动复制该服务到全部节点,不须要任何重启,更新一个服务也是同样.
要从命令行热部署一个服务你须要拷贝Python模块到pick-up目录
本教程中你能够在$path/server1/pickup-dir
和$path/server2/pickup-dir
中任选一个,都不会有问题,另外一个目录会自动同步
好了,选择一个目录拷贝模块:
$ cp my_service.py $path/server1/pickup-dir
如今,每一个server的日志文件中(./logs/server.log
)会出现下面的内容
INFO - zato.hot-deploy.create:33 - Uploaded package id:[1], payload_name:[my_service.py]
一个服务能够在多个独立的通道,不一样的安全配置,传输协议,数据格式下被使用,因此你须要明确的告诉Zato外部程序怎样调用服务,咱们用浏览器打开http://localhost:8183/在web admin中进行配置
还记得前面生成的admin帐号的密码吗?不记得了能够参考https://zato.io/docs/admin/cli/update-password.html重置密码
在主菜单点击Services
,选择创建的集群,输入get-client
搜索服务,以下图:
虽然不能在外部访问,但已经能够证明咱们部署的服务已经存在
在web admin中,转到Connections -> Channels -> Plain HTTP,以下图
全部字段都应该是自解释的,在web admin手册中有详细介绍,强调服务命名的重要性是为了解耦一个服务可能对应多个通道的问题
至此,通道已经创建,全部server都自动更新了它们的HTTP配置,咱们能够用Curl来测试一下
$ curl localhost:11223/tutorial/first-service -d '{}' $
这里没有任何输出,是由于咱们的服务返回的None,输入数据被记录到某一个server的日志中了,咱们能够用grep命令查找确认一下
日志中咱们能够看到
INFO - {u'impl_name': u'my_service.GetClientDetails', u'name': u'my-service.get-client-details', u'cid': u'K226134078656111264088116403218497665719', u'invocation_time': datetime.datetime(2013, 5, 14, 7, 39, 47, 417059), u'job_type': None, u'data_format': u'json', u'slow_threshold': 99999, u'request.payload': '', u'wsgi_environ': {'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'gunicorn/0.16.1', 'SCRIPT_NAME': '', 'wsgi.input': <gunicorn.http.body.Body object at 0x4396a50>, 'REQUEST_METHOD': 'GET', 'HTTP_HOST': 'localhost:11223', 'PATH_INFO': '/tutorial/first-service', 'wsgi.multithread': False, 'QUERY_STRING': '', 'HTTP_CONNECTION': 'close', 'HTTP_ACCEPT': '*/*', 'HTTP_USER_AGENT': 'curl/7.22.0', 'wsgi.version': (1, 0), 'REMOTE_PORT': '42325', 'RAW_URI': '/tutorial/first-service', 'REMOTE_ADDR': '127.0.0.1', 'wsgi.run_once': False, 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f34db2fe270>, 'wsgi.multiprocess': False, 'wsgi.url_scheme': 'http', 'gunicorn.socket': <socket at 0x42e9290 fileno=25 sock=127.0.0.1:17011 peer=127.0.0.1:42325>, 'SERVER_NAME': 'localhost', 'SERVER_PORT': '11223', u'zato.http.response.headers': {u'X-Zato-CID': u'K226134078656111264088116403218497665719'}, 'wsgi.file_wrapper': <class gunicorn.http.wsgi.FileWrapper at 0x202e390>}, u'environ': {}, u'user_msg': u'', u'usage': 27, u'channel': u'http-soap'}
这就是第一部分.你创建了一个集群,一个服务,在热部署该服务后调用成功,以这一部分为基础,下一部分咱们把焦点放在业务功能上.