Ice系列--强大如我IceGrid
前言
IceGrid是一个提供服务定位和服务激活的组件,但它的功能远不止于此。从它的命名可以看出它的设计理念—网格计算(grid computing)。网格计算被定义为由一系列关联的廉价计算机组成的计算网络。将写好的应用运行于网格计算中的主机上,只是应用整个生命周期中一部分工作。虽然Ice为应用的各个组成部分的之间通信提供了基础设施(RPC通信框架),但是我们还会面临很多挑战:
- 如何安装升级网格计算中的应用
- 如何跟踪网格计算中运行的服务
- 如何分发负载到所有的主机
- 如何将服务从一个主机迁移到另外一个主机
- 如何快速添加一个主机到网格中
今天看到这些分布式应用也面临问题时,是不是立马会想到容器,K8S,这个当下比较主流的解决方案。要知道Ice在十几年前就实现了一个成熟解决方案--IceGrid。以下是它的特性:
- 定位服务(Location service)
- 按需激活服务器(On-demand server activation)
- 应用分发(Application distribution)
- 复制和负载均衡(Replication and load balancing)
- 会话和资源分配(Sessions and resource allocation)
- 自动故障恢复(Automatic failover)
- 动态查询(Dynamic queries)
- 管理(Adminstration)
- 部署(Deployment)
IceGrid使得开发人员摆脱了这些低级的任务,加快了应用构建,简化了应用部署管理。
原理框架
IceGrid主要有两个重要的组成:注册中心(registry)和节点(node)。注册中心主要是维护服务路由信息,以及一个客户端请求过来后,去启动指定服务器;
或者根据各个主机的负载情况,返回路由信息。节点可以看做一个服务器集合,管理着这些服务器。如下图,一个简单的IceGrid应用:

从客户端角度,registry就是一个名字服务,将间接代理标识串,如 SimplePrinter@PrinterAdapter,转化成服务器连接端点。
以一次客户端调用为例:
1.客户端先向注册中心发起定位请求,通过间接代理标识串获取到对象适配器(PrinterAdapter)的服务地址端口
2.通过服务地址端口与Server(PrinterServer)建立连接
3.调用checkedCast,检验对象(SimplePrinter)是否存在
4.如果服务对象存在,则发起远程调用过程。不存在则抛出异常

环境部署
软件包安装参考官方文档。本文章运行的环境是:ubuntu 16.04,ice 3.7.2
registry和node的启动脚本和配置文件见:https://github.com/GodMonking/ice-demo/tree/main/deploy
启动registry
配置文件registry.cfg:

# Registry properties
IceGrid.InstanceName=MKIceGrid Ice.Default.Locator=MKIceGrid/Locator:tcp -p 4061 IceGrid.Registry.ReplicaName=Master
#IceGrid.Registry.Client.Endpoints=tcp -p 4061
IceGrid.Registry.Client.Endpoints=tcp -p 4061
IceGrid.Registry.Server.Endpoints=tcp
IceGrid.Registry.Internal.Endpoints=tcp IceGrid.Registry.AdminPermissionsVerifier=MKIceGrid/NullPermissionsVerifier
IceGrid.Registry.AdminPermissionsVerifier=MKIceGrid/NullPermissionsVerifier
IceGrid.Registry.SSLPermissionsVerifier=MKIceGrid/NullSSLPermissionsVerifier
IceGrid.Registry.AdminSSLPermissionsVerifier=MKIceGrid/NullSSLPermissionsVerifier
IceGrid.Registry.Discovery.Interface=127.0.0.1 IceGrid.Registry.LMDB.MapSize=10
#注册中心数据保存路径
IceGrid.Registry.LMDB.Path=/data/ice-demo/deploy/registry
IceGrid.Registry.DynamicRegistration=1 IceGrid.Registry.Trace.Node=1
IceGrid.Registry.Trace.Replica=1 #
# Dummy username and password for icegridadmin.
#
IceGridAdmin.Username=foo
IceGridAdmin.Password=bar
执行命令:
/usr/bin/icegridregistry --Ice.Config=./config/registry.cfg --daemon
启动node
启动两个node节点
配置文件node.cfg:

# Node properties
#默认定位器,即注册中心的服务地址端口
Ice.Default.Locator=MKIceGrid/Locator:tcp -p 4061
IceGrid.Node.Endpoints=tcp
IceGrid.Node.Name=node1
#数据存储路径
IceGrid.Node.Data=/data/ice-demo/deploy/node1
#日志输出路径
IceGrid.Node.Output=/tmp/node1
IceGrid.Node.Trace.Replica=2
IceGrid.Node.Trace.Activator=3
IceGrid.Node.Trace.Adapter=3
IceGrid.Node.Trace.Server=3
拷贝node.cfg :cp node.cfg node2.cfg
修改配置node2.cfg结果如下:

# Node properties
Ice.Default.Locator=MKIceGrid/Locator:tcp -p 4061
IceGrid.Node.Endpoints=tcp
IceGrid.Node.Name=node2
IceGrid.Node.Data=/data/ice-demo/deploy/node2
IceGrid.Node.Output=/tmp/node2
IceGrid.Node.Trace.Replica=2
IceGrid.Node.Trace.Activator=3
IceGrid.Node.Trace.Adapter=3
IceGrid.Node.Trace.Server=3
执行命令:
/usr/bin/icegridnode --Ice.Config=./config/node.cfg –daemon
/usr/bin/icegridnode --Ice.Config=./config/node2.cfg –daemon
通过命令行工具查看是否部署成功:
/usr/bin/icegridadmin -H localhost -P 4061

由于注册中心没有开启鉴权,所以这里账号密码任意输入。
也可以通过IceGrid GUI工具查看。Windows下安装IceGrid GUI,打开IceGrid GUI,新建一个连接,登录注册中心


服务部署
部署配置文件,客户端程序和服务端程序代码见:
https://github.com/GodMonking/ice-demo/tree/main/IceGrid/Printer
简单应用开发
服务端部分代码:

int
main(int argc, char* argv[])
{
try
{
if (argc < 2)
{
cerr << "not input config file" << endl;
return 1;
} Ice::CommunicatorHolder ich(argc, argv);
auto communicator = ich.communicator();
auto properties = communicator->getProperties();
cout << "adapter: " << properties->getProperty("SimplePrinterAdapter.AdapterId") << endl;
//注意这里的对象适配器名字要与下文的部署配置中的adaptor的属性name保持一致
auto adapter = ich->createObjectAdapter("SimplePrinterAdapter");
auto servant = make_shared<PrinterI>();
adapter->add(servant, Ice::stringToIdentity("SimplePrinter"));
adapter->activate();
cout << "activate complete..." << endl;
ich->waitForShutdown();
}
catch(const std::exception& e)
{
cerr << e.what() << endl;
return 1;
}return 0;
}
客户端程序代码:

#include <Ice/Ice.h>
#include <Printer.h>
#include <stdexcept> using namespace std;
using namespace Demo; int
main(int argc, char* argv[])
{
try
{
//Ice::CommunicatorHolder ich(argc, argv, "config.client");
Ice::CommunicatorHolder ich(argc, argv);
auto base = ich->stringToProxy("SimplePrinter@SimplePrinterAdapter");
auto printer = Ice::checkedCast<PrinterPrx>(base);
if(!printer)
{
throw std::runtime_error("Invalid proxy");
} printer->printString("Hello World!");
}
catch(const std::exception& e)
{
cerr << e.what() << endl;
return 1;
}
return 0;
}
"SimplePrinter@SimplePrinterAdapter"表示一个间接代理的标识字符串,
SimplePrinterAdapter表示对象适配器ID,对应下文部署配置中adaptor的属性id值。
客户端配置文件config.client:
Ice.Default.Locator=MKIceGrid/Locator:tcp -p 4061
上述配置表示一个定位器,定位器即注册中心提供服务地址端口。
部署配置文件
应用程序部署配置文件主要是向注册中心描述几个重要元素:Nodes,Servers,Object adaptors,Objects。如下图配置文件:
<icegrid>
<application name="Ripper">
<node name="node1">
<server id="PrinterServer" exe="/data/ice-demo/IceGrid/Printer/server" activation="on-demand">
<adapter name="SimplePrinterAdapter" id="SimplePrinterAdapter" endpoints="tcp"/>
<property name="Ice.Trace.Network" value="1"/>
<property name="Ice.PrintStackTraces" value="1"/>
<property name="Ice.Admin.Endpoints" value="tcp" />
</server>
</node>
</application>
</icegrid>
上图中,元素node描述了server归属于node1节点,即表明PrinterServer部署在node1所在主机上。元素server的属性exe则描述可执行文件的路径,
属性activation描述服务器激活方式,“on-demand”表示按需激活,即有请求达到时才被激活。元素adaptor描述了对象适配器(Object adaptor)的信息。
通过IceGrid GUI部署应用
点击如下箭头所指按钮

打开配置文件

加载之后生成表单,如下;点击箭头所指按钮,将配置保存到注册中心

可以看到node1下面已经有服务PrinterServer

验证服务
执行客户端程序
./client --Ice.Config=config.client
可以看到服务被激活

选择服务右击鼠标,查看标准输出信息:

结尾
IceGrid不仅提供了定位服务,负载均衡等功能,同时还简化了服务发布和部署。本文介绍了IceGrid的一个简单应用,后续文章会介绍它的高级部署模式。
Ice系列--强大如我IceGrid的更多相关文章
- Ice系列--基于IceGrid的部署方案
前言 前一篇文章介绍了IceGrid的简单应用.这篇文章来介绍一下它的高端玩法-如何将模板,复制组,知名对象应用于部署方案及其作用. 基于模板的部署方案 之前介绍了xml格式的配置文件通过各种描述符如 ...
- 深入浅出Mybatis系列 强大的动态SQL
上篇文章<深入浅出Mybatis系列(八)---mapper映射文件配置之select.resultMap>简单介绍了mybatis的查询,至此,CRUD都已讲完.本文将介绍mybatis ...
- Ice系列--傻瓜式服务开发IceBox
前言 相信大家在没有接触过框架之前,都自己或多或少的开发过一些应用服务.每个应用服务除了业务配置还有很多环境配置,资源配置等,这些跟部署相关的配置.服务跟配置文件是一种静态绑定的方式,更新配置还需要重 ...
- ICE系列之3对象接口定义语言——slice
Slice 定义由编译器编译到特定的实现语言 .编译器把与语言无关的定 义翻译成针对特定语言的类型定义和 API.开发者使用这些类型和 API 来 提供应用功能,并与 Ice 交互.用于各种 ...
- ICE系列之2——ICE的服务与好处
ice服务: IcePack 我们在第 12 页提到过, IcePack 是 Ice 的定位服务,用于在使用间接绑定时把符号性的 (symbolic)适配器名解析为协议-地址对. 除了 ...
- ZeroC Ice IceGrid Node和IceGrid
IceGrid Node介绍 绝大多数分布式系统都有一个共同特点,即分布在各个主机上的节点进程并不是完全独立的,而是彼此之间有相互联系和通信的.集群对集群中的节点有一些控制指令,如部署.启停或者调整某 ...
- ice介绍 z
什么是ICE(Internet Communications Engine)呢,它是由Zeroc公司开 发的一套开源中间件系统,与DCOM,CORBA,WEB SERVICEDcom类似,支持RPC( ...
- IceGrid负载均衡部署 z
[IceGrid负载均衡部署步骤]1.环境主机1:IP=192.168.0.239,上面部署注册表服务器registry和节点node1,registry和node1运行在同一进程中:主机2:IP=1 ...
- 使用spring boot和thrift、zookeeper建立微服务
Spring cloud适应于云端服务,也适用于企业信息化SOA建设.spring boot也是restful微服务开发的利器.但对于内网服务,即服务与服务之间的调用,spring并没有去刻意封装,也 ...
随机推荐
- Java后端使用socketio,实现小程序答题pk功能
在使用socket.io跟前端通信过程中,出现了一系列问题,现做下记录. 一.功能需求是,在小程序端,用户可相互邀请,进入房间后进行答题PK.实现方法是,用户点击邀请好友,建立连接,查询当前是否有房间 ...
- Go加密算法总结
前言 加密解密在实际开发中应用比较广泛,常用加解密分为:"对称式"."非对称式"和"数字签名". 对称式:对称加密(也叫私钥加密)指加密和解 ...
- [GXYCTF2019]禁止套娃(无参RCE)
[GXYCTF2019]禁止套娃 1.扫描目录 扫描之后发现git泄漏 使用githack读取泄漏文件 <?php include "flag.php"; echo &quo ...
- mysqldump 导出命令
在命令行下mysql的数据导出有个很好用命令mysqldump,它的参数有一大把,可以这样查看: mysqldump 最常用的: mysqldump -uroot -pmysql databasefo ...
- App性能测试揭秘(Android篇)
阿里云 云原生应用研发平台EMAS 李嘉华(千瞬) 简介: 性能测试在移动测试领域一直是一个大难题,它最直观的表现是用户在前台使用 App 时的主观体验,然而决定体验优劣的背后,涉及到了许许多多的技术 ...
- jxl导出Excel中需要跳过的的坑
正如上篇文章(JXL封装不能使用static关键字问题)所说,在jxl导出Excel时候如果频繁使用到WritableCellFormat去设置单元格的样式,这个时候经常会出现两种情况: 1.报警告: ...
- Core3.0使用Caching.Memory
前言 参考链接: 使用缓存:https://www.cnblogs.com/gygg/p/11275417.html 过期时间:https://www.cnblogs.com/maijin/p/704 ...
- 安装篇五:安装MySQL(5.6.38版本)
#1.MySQL安装 #1.准备环境 # No1:关闭:(iptables)selinux # No2:下载好安装包(这里使用 mysql-5.6.38.tar.gz 包安装) # No3:安装依赖包 ...
- 发送微信通知 java
//实现类@Service public class WeChatServiceImpl implements IWeChatService { @Override public WeChatSend ...
- java面试 题
分布式消息队列 1,为什么使用消息队列啊消息队列有什么优点和缺点啊 2,如何保证消息队列的高可用啊如何保证消息不被重复消费啊 3,kafka,activemq,rabbitmq,rocketmq都有什 ...