前言

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的更多相关文章

  1. Ice系列--基于IceGrid的部署方案

    前言 前一篇文章介绍了IceGrid的简单应用.这篇文章来介绍一下它的高端玩法-如何将模板,复制组,知名对象应用于部署方案及其作用. 基于模板的部署方案 之前介绍了xml格式的配置文件通过各种描述符如 ...

  2. 深入浅出Mybatis系列 强大的动态SQL

    上篇文章<深入浅出Mybatis系列(八)---mapper映射文件配置之select.resultMap>简单介绍了mybatis的查询,至此,CRUD都已讲完.本文将介绍mybatis ...

  3. Ice系列--傻瓜式服务开发IceBox

    前言 相信大家在没有接触过框架之前,都自己或多或少的开发过一些应用服务.每个应用服务除了业务配置还有很多环境配置,资源配置等,这些跟部署相关的配置.服务跟配置文件是一种静态绑定的方式,更新配置还需要重 ...

  4. ICE系列之3对象接口定义语言——slice

         Slice 定义由编译器编译到特定的实现语言 .编译器把与语言无关的定 义翻译成针对特定语言的类型定义和 API.开发者使用这些类型和 API 来 提供应用功能,并与 Ice 交互.用于各种 ...

  5. ICE系列之2——ICE的服务与好处

    ice服务: IcePack         我们在第 12 页提到过, IcePack 是 Ice 的定位服务,用于在使用间接绑定时把符号性的 (symbolic)适配器名解析为协议-地址对. 除了 ...

  6. ZeroC Ice IceGrid Node和IceGrid

    IceGrid Node介绍 绝大多数分布式系统都有一个共同特点,即分布在各个主机上的节点进程并不是完全独立的,而是彼此之间有相互联系和通信的.集群对集群中的节点有一些控制指令,如部署.启停或者调整某 ...

  7. ice介绍 z

    什么是ICE(Internet Communications Engine)呢,它是由Zeroc公司开 发的一套开源中间件系统,与DCOM,CORBA,WEB SERVICEDcom类似,支持RPC( ...

  8. IceGrid负载均衡部署 z

    [IceGrid负载均衡部署步骤]1.环境主机1:IP=192.168.0.239,上面部署注册表服务器registry和节点node1,registry和node1运行在同一进程中:主机2:IP=1 ...

  9. 使用spring boot和thrift、zookeeper建立微服务

    Spring cloud适应于云端服务,也适用于企业信息化SOA建设.spring boot也是restful微服务开发的利器.但对于内网服务,即服务与服务之间的调用,spring并没有去刻意封装,也 ...

随机推荐

  1. Linux相关-回顾-文件和目录(98.1.1)

    @ 目录 1.linux下的文件系统 2.用户目录 3.Linux 主要目录速查表 关于作者 1.linux下的文件系统 在 Linux 下,我们是看不到这些驱动器盘符,我们看到的是文件夹(目录): ...

  2. bugku 之 crypto:进制转换的python脚本

    题目如下: text.txt的内容: 知识点:python怎么做进制转换 除了自己按照计算方法写一遍进制转换,可以用python自带的强制转换: int(a,num) 其中,int是转换成十进制整数类 ...

  3. tomcat8默认umask已改为027

    1. umask的简单介绍 不过我们通常只用后三位,同样对应属主属组以及其他用户的权限,例如你的账号umask值为0022(可直接通过umask命令查看), 此时你创建的文件权限默认为644(文件初始 ...

  4. Python机器学习课程:线性回归算法

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 最基本的机器学习算法必须是具有单个变量的线性回归算法.如今,可用的高级机器学习算法,库和技术如此之多 ...

  5. python菜鸟教程基础入门

    一. 可以使用'\'来连接多行.但是有括号的则不需要 a=b+\ c+\ d a1=['a', 'b'] 引号可以是单,双,三引号均可 二. 1. python有5个标准类型:数字,字符串,列表,元组 ...

  6. 图解JanusGraph系列 - JanusGraph指标监控报警(Monitoring JanusGraph)

    大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步(超链):图数据库系列-文章总目录 源码分析相关可查看github(码文不易,求个sta ...

  7. C#访问Access数据库提示未安装ISAM

    解决办法 1.在前面加上Jet OLEDB:,如: Jet OLEDB:Database Password='zt' <add name="ConStrOleDb" conn ...

  8. sql server 汉字转拼音首字母

    create function fun_getPY ( @str nvarchar(4000) ) returns nvarchar(4000) as begin declare @word ncha ...

  9. Raft算法系列教程3:日志复制

    1.日志复制的过程 Leader选出后,就开始接收客户端的请求.Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC ...

  10. hive中笛卡尔积的优化

    由于一个业务,必须要进行笛卡尔积,但是速度太慢了,left join时左表大概4万条数据,右表大概 3000多条数据,这样大概就是一亿多条数据, 这在大数据领域其实不算很大的数据量,但是hive中跑的 ...