如何用python开发Zeroc Ice应用
作者:高艳兵 发布时间:2022-06-23 01:17:50
Zeroc Ice简介
Zeroc ICE(Internet Communications Engine ,互联网通信引擎)是目前功能比较强大和完善的RPC框架,支持跨平台、跨语言调用。它非常灵活,可以通过TCP、UDP、SSL/TSL或WebSocket连接,支持同步、异步调用,以及服务器和客户端之间的双向连接。Zeroc ICE的效率非常高,它使用一种高效的二进制协议,对带宽的消耗比较小。甚至对于通过卫星的RPC调用,Zeroc ICE还可以对数据流进一步压缩。另外Zeroc ICE还可以在不解包的情况下转发调用请求,省去普通转发时的解包、重新压包的时间。
Zeroc ICE的应用还可以部署在icegrid上,实现网格计算,即客户端调用时不必指定目标主机,由ICE负责查找;服务端也可以在调用时才开启,动态加载;同样的服务也可以部署多个,实现高可用。
实验简介
Zeroc ICE支持跨语言RPC调用,包括C++、C#、Java、JavaScript、Python、Objective-C、Ruby、PHP、VB等。本次实验采用Python(Pyhon 2.7以上,或者Python 3都可以)。实验的内容是在icegrid上部署一个简单的服务器,当客户端调用时输出指定内容,并返回一个字符串。实验步骤如下:
安装Zeroc ICE
开发服务端和客户端程序
部署到icegrid
客户端调用
环境准备
本次实验采用的操作系统是Ubuntu 14.04。如果使用其他操作系统,可以根据Zeroc ICE的文档相应调整。
安装Zeroc Ice
如果系统中没有安装Zeroc ICE,并且ubuntu的软件源中也没有zeroc ice,可以按照下面的步骤安装。
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 5E6DA83306132997
sudo apt-add-repository "deb http://zeroc.com/download/apt/ubuntu$(lsb_release -rs) stable main"
sudo apt-get update
sudo apt-get install zeroc-ice-all-runtime zeroc-ice-all-dev
安装之后系统中就有了slice2cpp、slice2java等Sliece(Zeroc ICE定义的接口描述语言,IDL)文件到相应语言的转换程序,以及icegrid、iceregistry、icegridadmin等程序。如果缺少目标语言的工具(例如slice2py)或开发包,还需要特别安装。
安装Zeroc ICE的python开发包
当然在这一步之前应当首先安装python和pip(python的依赖管理工具),此处略。Zeroc ICE的python开发包(或者模块)叫zeroc-ice,可以使用pip安装。
sudo -H pip install zeroc-ice
安装过程中可能出现缺少某些C/C++头文件的问题,例如缺少python.h、openssl/ssl.h、bzlib.h,这些都是因为没有安装相应的开发包。可以通过如下的命令解决:
sudo apt-get install python-dev
sudo apt-get install libssl-dev
sudo apt-get install libbz2-dev
开发Server和Client
下面即是真正的服务端和客户端开发。开发过程通常是:
使用Slice语言定义语言无关的接口文件
转换成指定语言的接口文件
根据接口文件开发服务端和客户端程序
书写服务端和客户端的配置文件
使用slice语言定义接口
// Printer.ice
module Demo {
interface Printer {
string printString(string s);
};
};
生成指定语言的接口文件
本次开发采用的语言是python,所以使用
slice2py Printer.ice
其他语言可以依此类推,例如slice2java,slice2cpp。
命令执行成功,可以看到在目标目录中生成了一个Printer_ice.py文件,以及一个Demo目录。Demo是slice接口文件中定义的module名称。
编写服务器
import sys, traceback, Ice
import Demo
# PrinterI是接口实现类,Demo.Printer是slice2py生成的接口
class PrinterI(Demo.Printer):
def printString(self, s, current=None):
print(s)
return "Server Printed: " + s
status = 0
ic = None
try:
# 初始化zeroc ice环境
ic = Ice.initialize(sys.argv)
# 生成名为SimplePrinterAdapter的对象适配器,连接方式是缺省的tcp,监听端口10000
adapter = ic.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000")
# 生成接口的实现对象,并以指定的名字SimplePrinter添加到对象适配器中
object = PrinterI()
adapter.add(object, ic.stringToIdentity("SimplePrinter"))
# 激活对象适配器
adapter.activate()
# 使得本服务器的调用线程在此暂停,直至ice服务结束,或者进程结束
ic.waitForShutdown()
except:
traceback.print_exc()
status = 1
if ic:
# Clean up
try:
ic.destroy()
except:
traceback.print_exc()
status = 1
sys.exit(status)
server.cfg内容如下:
PrinterAdapter.AdapterId=PrinterAdapter
PrinterAdapter.Endpoints=tcp
其中tcp的意思通过tcp协议调用,服务器监听来自tcp协议的连接请求。
编写客户端
import sys, traceback, Ice
import Demo
status = 0
ic = None
try:
ic = Ice.initialize(sys.argv)
# 生成名为SimplePrinter代理对象,且通过tcp调用,连接目标机器的10000端口
base = ic.stringToProxy("SimplePrinter:default -p 10000")
# 将代理对象转换成目标对象
printer = Demo.PrinterPrx.checkedCast(base)
if not printer:
raise RuntimeError("Invalid proxy")
# 调用服务器的printString方法,并输出返回结果
rs = printer.printString("Hello World, I'm talking to you through RPC")
print(rs)
except:
traceback.print_exc()
status = 1
if ic:
# Clean up
try:
ic.destroy()
except:
traceback.print_exc()
status = 1
sys.exit(status)
客户端的配置文件如下:
Ice.Default.Locator=SzcIceGrid/Locator:tcp -h 127.0.0.1 -p 4061
客户端直连服务端
上述程序开发完毕之后不用部署到icegrid就可以直接运行,配置文件是用来在icegrid上定位和连接服务。此时可以一边运行服务端,一边运行客户端,检验一下它们的功能。
python Server.py
运行之后可以看到进程并没有结束,一直在等待连接。然后另起一个终端,运行客户端程序。
python Client.py
运行之后可以看到服务端和客户端窗口的输出。
部署到icegrid
icegrid是Zeroc ICE的云计算解决方案。它可以将各种服务端部署在多台机器上,并为客户端调用提供服务定位、服务激活、负载均衡、故障转移等服务。客户端只要连接到指定的服务注册中心,就可以根据服务名称(这里是SimplePrinter),以及连接协议(Endpoints,这里是tcp)就可以找到相应的服务。服务在注册时也不必处在运行状态,可以由icegrid根据调用请求,自动启动。
配置注册中心
registry.cfg(服务注册中心的配置文件)
IceGrid.InstanceName=SzcIceGrid
#客户端连接到注册中心的地址
IceGrid.Registry.Client.Endpoints=tcp -p 4061
IceGrid.Registry.Server.Endpoints=tcp
IceGrid.Registry.Internal.Endpoints=tcp
IceGrid.Registry.PermissionsVerifier=SzcIceGrid/NullPermissionsVerifier
IceGrid.Registry.AdminPermissionsVerifier=SzcIceGrid/NullPermissionsVerifier
#注册中心数据保存路径,需要手动创建文件夹
IceGrid.Registry.Data=/home/rocway/test/zerocice/registry
IceGrid.Registry.DynamicRegistration=1
Ice.Admin.InstanceName=AdminInstance
Ice.Admin.ServerId=Admin
注意:手工创建文件中的路径。
配置节点
节点是服务所在的机器。在实际生产环境中,服务注册中心也可以运行在其中某个节点上。
node1.cfg(服务所在节点的配置文件)
# 注册中心地址
Ice.Default.Locator=SzcIceGrid/Locator:tcp -h 127.0.0.1 -p 4061
#node名
IceGrid.Node.Name=node1
IceGrid.Node.Endpoints=tcp
#node存储路径
IceGrid.Node.Data=/home/rocway/test/zerocice/nodes/node1
IceGrid.Node.Output=/home/rocway/test/zerocice/nodes/node1
IceGrid.Node.CollocateRegistry=0
注意:手工创建上述文件中提到的路径。其中服务端程序的输出会保存在Ouput指向路径的*.out文件中。
应用描述文件
应用描述文件用来描述服务端程序在icegrid中的部署情况。包括应用的名称、服务程序的路径、执行参数等等。
app.xml
<icegrid>
<application name="PrinterApplication">
<node name="node1">
<server id="PrinterServer" exe="python" activation="on-demand">
<adapter name="PrinterAdapter" endpoints="tcp -h 127.0.0.1">
<object identity="SimplePrinter" type="::Demo::Printer" property="Identity"/>
</adapter>
<option>/home/rocway/test/zerocice/Server.py</option>
<property name="Ice.Trace.Network" value="1"/>
<properties>
<property name="Ice.ThreadPool.Server.SizeMax" value="1" />
</properties>
<property name="IceMX.Metrics.Debug.GroupBy" value="id"/>
<property name="IceMX.Metrics.Debug.Disabled" value="1"/>
<property name="IceMX.Metrics.ByParent.GroupBy" value="parent"/>
<property name="IceMX.Metrics.ByParent.Disabled" value="1"/>
</server>
</node>
</application>
</icegrid>
启动icegrid
1.启动icegrid注册中心
icegridregistry --Ice.Config=registry.cfg
2.启动某个节点
icegridnode --Ice.Config=node1.cfg
3.启动节点上的应用管理程序, 并添加应用
icegridadmin --Ice.Config=node1.cfg
application add app.xml
4.查看已经添加的应用
application describe PrinterApplication
5.启动各节点上的应用服务
icegridgui
6.运行客户端程序
python Client.py
实验总结
此次实验实现了在icegrid上部署服务程序,客户端通过icegrid的服务注册中心调用该服务。实验中服务端和客户端使用的都是Python,有兴趣的同学也可以分别使用不同的语言开发服务端和客户端,尝试一下Zeroc ICE的跨语言RPC调用。
本次实验就到这里,有关Zeroc ICE的其他内容请关注后续的课程。
来源:https://www.cnblogs.com/gaoyanbing/p/14336395.html


猜你喜欢
- #coding:utf-8 #批量修改文件名 import os import re import datetime re_st = r
- list count统计个数实现在python数组中统计某个数字出现的次数。。。。。count_num = 3lst = [1,2,3,4,
- 数据处理在现代企业运营中变得越来越重要,越来越关键,甚至会成为企业发展的一项瓶颈. 数据保护的重要性也不言而喻. 如果一个企业没有很好的数据
- 1、前不久,friendfeed.com把主导航从上面,移到了右侧。现在,又改到了左侧。2、现在,twitter.com把页签(相当于二级导
- 1. torch.utils.data.Datasetdatasets这是一个pytorch定义的dataset的源码集合。下面是一个自定义
- 尽管 xml.etree.ElementTree 库通常用来做解析工作,其实它也可以创建XML文档。 例如,考虑如下这个函数:from xm
- 使用base64还原由图片加密而成的字符串。Raw字符串:iVBORw0KGgoAAAANSUhEUgAAAtoAAALaCAYAAAAP7
- Ubuntu 18.04下1、安装python 2._版本,输入 sudo apt install python命令行输入 python或p
- 本文实例为大家分享了Python实现学生信息管理系统的具体代码,供大家参考,具体内容如下要求描述:学生的信息包括:学号,姓名,年龄,性别,出
- 数据探索性分析(EDA)1. 总览数据概况数据库载入#coding:utf-8#导入warnings包,利用过滤器来实现忽略警告语句。imp
- SQL Server具有强大的复制功能,除了将数据和数据库对象从一个数据库复制并准确分发的另一个数据库中,还要实行数据库之间的同步。SQL
- 就我个人经验来讲:除了oracle,没有比HP 客户支持中心更糟糕的体验了。刚买不到一个月的HP MINI笔记本,莫名其妙键盘上的引号键松动
- PDF是我们经常会接触到的一种文件格式,文献、文档...很多都是PDF格式。它以格式稳定的优势,使得我们在打印、分享、传输过程中能够最优的保
- <?php 02 if(!function_exists('get_headers')){ 03&
- 程序员的时间很宝贵,Python这门语言虽然足够简单、优雅,但并不是说你使用Python编程,效率就一定会高。要想节省时间、提高效率,还是需
- Python关键字 global与nonlocalglobaldef test(): #1函数内如果没定义x,则x默认为全局变量
- 前言最近学习scrapy爬虫框架,在使用pycharm安装scrapy类库及创建scrapy项目时花费了好长的时间,遇到各种坑,根据网上的各
- 本文介绍基于Python中ArcPy模块,对大量栅格遥感影像文件进行批量掩膜与批量重采样的操作。首先,我们来明确一下本文的具体需求。现有一个
- 要解决两个需求: 一个是从A页面跳到B页面,滚动到页面的任何地方; 第二个是在B页面内部点击某个元素,滚动到页面的任何地方; 怎么解决啊?很
- 如下所示:import matplotlib.pyplot as pltimport numpy as npdef readfile(fil