Index
源码链接
ICE
Hello.ice
#pragma once
module Demo
{
interface Hello
{
idempotent void sayHello();
void shutdown();
}
}
客户端
Client.cpp
#include <Ice/Ice.h>
#include <IceGrid/IceGrid.h>
#include <Hello.h>
using namespace std;
using namespace Demo;
int run(const Ice::CommunicatorPtr&);
int
main(int argc, char* argv[])
{
#ifdef ICE_STATIC_LIBS
Ice::registerIceSSL();
Ice::registerIceLocatorDiscovery();
#endif
int status = 0;
try
{
//
// CommunicatorHolder's ctor initializes an Ice communicator,
// and its dtor destroys this communicator.
//
Ice::CommunicatorHolder ich(argc, argv, "config.client");//读取配置文件初始化通信器
//
// The communicator initialization removes all Ice-related arguments from argc/argv
//
if(argc > 1)
{
cerr << argv[0] << ": too many arguments" << endl;
status = 1;
}
else
{
status = run(ich.communicator());
}
}
catch(const std::exception& ex)
{
cerr << argv[0] << ": " << ex.what() << endl;
status = 1;
}
return status;
}
void
menu()
{
cout <<
"usage:\n"
"t: send greeting\n"
"s: shutdown server\n"
"x: exit\n"
"?: help\n";
}
int
run(const Ice::CommunicatorPtr& communicator)
{
//
// First we try to connect to the object with the `hello'
// identity. If it's not registered with the registry, we
// search for an object with the ::Demo::Hello type.
//
HelloPrx hello;
try
{
hello = HelloPrx::checkedCast(communicator->stringToProxy("hello"));
}
catch(const Ice::NotRegisteredException&)
{
IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(communicator->stringToProxy("DemoIceGrid/Query"));
hello = HelloPrx::checkedCast(query->findObjectByType("::Demo::Hello"));
}
if(!hello)
{
cerr << "couldn't find a `::Demo::Hello' object." << endl;
return 1;
}
menu();
char c = 'x';
do
{
try
{
cout << "==> " << flush;
cin >> c;
if(c == 't')
{
hello->sayHello();
}
else if(c == 's')
{
hello->shutdown();
}
else if(c == 'x')
{
// Nothing to do
}
else if(c == '?')
{
menu();
}
else
{
cout << "unknown command `" << c << "'" << endl;
menu();
}
}
catch(const Ice::Exception& ex)
{
cerr << ex << endl;
}
}
while(cin.good() && c != 'x');
return 0;
}
服务器
HelloI.h
## HelloI.cpp
#ifndef HELLO_I_H
#define HELLO_I_H
#include <Hello.h>
class HelloI : public Demo::Hello
{
public:
HelloI(const std::string&);
virtual void sayHello(const Ice::Current&);
virtual void shutdown(const Ice::Current&);
private:
// Required to prevent compiler warnings with MSVC++
HelloI& operator=(const HelloI&);
const std::string _name;
};
#endif
HelloI.cpp
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
#include <Ice/Ice.h>
#include <HelloI.h>
using namespace std;
HelloI::HelloI(const string& name) : _name(name)
{
}
void
HelloI::sayHello(const Ice::Current&)
{
cout << _name << " says Hello World!" << endl;
}
void
HelloI::shutdown(const Ice::Current& c)
{
cout << _name << " shutting down..." << endl;
c.adapter->getCommunicator()->shutdown();
}
Server.cpp
#include <Ice/Ice.h>
#include <HelloI.h>
using namespace std;
//
// Global variable for shutdownCommunicator
//
Ice::CommunicatorPtr communicator;
//
// Callback for CtrlCHandler
//
void
shutdownCommunicator(int)
{
communicator->shutdown();
}
int
main(int argc, char* argv[])
{
int status = 0;
try
{
//
// CtrlCHandler must be created before the communicator or any other threads are started
//
Ice::CtrlCHandler ctrlCHandler;
//
// Set the 'BuildId' property displayed in the IceGridAdmin GUI
//
Ice::InitializationData initData;
initData.properties = Ice::createProperties();
initData.properties->setProperty("BuildId", string("Ice ") + ICE_STRING_VERSION);
//
// CommunicatorHolder's ctor initializes an Ice communicator,
// and it's dtor destroys this communicator.
//
Ice::CommunicatorHolder ich(argc, argv, initData);
communicator = ich.communicator();
//
// Shutdown communicator on Ctrl-C
//
ctrlCHandler.setCallback(&shutdownCommunicator);
//
// The communicator initialization removes all Ice-related arguments from argc/argv
//
if(argc > 1)
{
cerr << argv[0] << ": too many arguments" << endl;
status = 1;
}
else
{
Ice::PropertiesPtr properties = communicator->getProperties();
Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("Hello");
Ice::Identity id = Ice::stringToIdentity(properties->getProperty("Identity"));
Demo::HelloPtr hello = new HelloI(properties->getProperty("Ice.ProgramName"));
adapter->add(hello, id);
adapter->activate();
communicator->waitForShutdown();
}
}
catch(const std::exception& ex)
{
cerr << ex.what() << endl;
status = 1;
}
return status;
}
客户端配置
config.client
#
# The IceGrid locator proxy
# 配置定位器的代理
Ice.Default.Locator=DemoIceGrid/Locator:default -h localhost -p 4061
#
# To use the IceGrid discovery plugin comment out the default locator
# property above and un-comment the two properties below. The discovery
# plugin uses multicast to discover IceGrid.
#
#Ice.Plugin.IceLocatorDiscovery=IceLocatorDiscovery:createIceLocatorDiscovery
#IceLocatorDiscovery.InstanceName=DemoIceGrid
icegridnode服务配置
config.grid
#
# The IceGrid instance name.
#
IceGrid.InstanceName=DemoIceGrid
#
# The IceGrid locator proxy.
#
Ice.Default.Locator=DemoIceGrid/Locator:default -h localhost -p 4061
#
# IceGrid registry configuration.
#
IceGrid.Registry.Client.Endpoints=default -h localhost -p 4061
IceGrid.Registry.Server.Endpoints=default -h localhost
IceGrid.Registry.Internal.Endpoints=default -h localhost
IceGrid.Registry.LMDB.Path=db/registry
IceGrid.Registry.PermissionsVerifier=DemoIceGrid/NullPermissionsVerifier
IceGrid.Registry.AdminPermissionsVerifier=DemoIceGrid/NullPermissionsVerifier
IceGrid.Registry.SSLPermissionsVerifier=DemoIceGrid/NullSSLPermissionsVerifier
IceGrid.Registry.AdminSSLPermissionsVerifier=DemoIceGrid/NullSSLPermissionsVerifier
IceGrid.Registry.Discovery.Interface=127.0.0.1
#
# IceGrid node configuration.
#
IceGrid.Node.Name=node1
IceGrid.Node.Endpoints=default -h localhost
IceGrid.Node.Data=db/node
IceGrid.Node.CollocateRegistry=1
#IceGrid.Node.Output=db
#IceGrid.Node.RedirectErrToOut=1
#
# IceMX configuration
#
IceMX.Metrics.Debug.GroupBy=id
IceMX.Metrics.Debug.Disabled=1
IceMX.Metrics.Debug.Reject.parent=Ice\.Admin
IceMX.Metrics.ByParent.GroupBy=parent
IceMX.Metrics.ByParent.Disabled=1
#
# Trace properties.
#
IceGrid.Node.Trace.Activator=1
#IceGrid.Node.Trace.Adapter=2
#IceGrid.Node.Trace.Server=3
#
# Dummy username and password for icegridadmin.
#
IceGridAdmin.Username=foo
IceGridAdmin.Password=bar
application.xml
<!-- Copyright (c) ZeroC, Inc. All rights reserved. -->
<icegrid>
<application name="Simple">
<node name="node1">
<server id="SimpleServer" exe="./server" activation="on-demand">
<adapter name="Hello" endpoints="tcp -h localhost">
<object identity="hello" type="::Demo::Hello" property="Identity"/>
</adapter>
<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>
application_with_template.xml
<!-- Copyright (c) ZeroC, Inc. All rights reserved. -->
<icegrid>
<application name="Simple">
<server-template id="SimpleServer">
<parameter name="index"/>
<server id="SimpleServer-${index}" exe="./server" activation="on-demand">
<adapter name="Hello" endpoints="tcp -h localhost">
<object identity="hello-${index}" type="::Demo::Hello" property="Identity"/>
</adapter>
<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>
</server-template>
<node name="node1">
<server-instance template="SimpleServer" index="1"/>
<server-instance template="SimpleServer" index="2"/>
<server-instance template="SimpleServer" index="3"/>
</node>
</application>
</icegrid>
application_with_replication.xml
<!-- Copyright (c) ZeroC, Inc. All rights reserved. -->
<icegrid>
<application name="Simple">
<server-template id="SimpleServer">
<parameter name="index"/>
<server id="SimpleServer-${index}" exe="./server" activation="on-demand">
<adapter name="Hello" endpoints="tcp -h localhost" replica-group="ReplicatedHelloAdapter"/>
<property name="Identity" value="hello"/>
<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>
</server-template>
<replica-group id="ReplicatedHelloAdapter">
<load-balancing type="round-robin"/>
<object identity="hello" type="::Demo::Hello"/>
</replica-group>
<node name="node1">
<server-instance template="SimpleServer" index="1"/>
<server-instance template="SimpleServer" index="2"/>
<server-instance template="SimpleServer" index="3"/>
</node>
</application>
</icegrid>
部署
启动IceGrid服务
icegridnode --Ice.Config=config.grid
部署服务程序
- 部署一个服务实例
icegridadmin --Ice.Config=config.grid -e "application add application.xml"
更新部署
- 使用配置模板来创建多个相同的服务实例
icegridadmin --Ice.Config=config.grid -e "application update application_with_template.xml"
- 使用多个服务复制来均衡负载
icegridadmin --Ice.Config=config.grid -e "application update application_with_replication.xml"
- 使用以上配置文件部署服务后,就可以轻松部署更多基于SimpleServer模板的服务器了
icegridadmin --Ice.Config=config.grid -e "server template instantiate Simple node1 SimpleServer index=4"
启动客户端测试
- ./client
- server log:
- 多客户端负载均衡
- 多客户端负载均衡