系统安装ice3.4.1,并配置环境变量;

定义slice文件

1
2
3
4
5
6
7
8
9
10
[[ "java:package:com.hhly.tel.ice"]]
module book {
interface OnlineBook {
void bookTick(string name,double price,string content);
};

interface SMSService {
void sendSMS(string name,double price,string content);
};
};

这表示有2个接口,一个OnlineBook,一个SMSService,都位于com.hhly.tel.ice.book下面。

生成JAVA类

使用slice2java xx.ice生成

然后将生成的类复制到工程中

上图中圈红的都是ice生成的类。

实现我们自己的逻辑

如上图的service下面,是OnlineBook和SMSService的实现,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.hhly.tel.ice.book.service;
import Ice.Communicator;
import Ice.Current;
import Ice.ObjectAdapter;
import IceBox.Service;
import com.hhly.tel.ice.book._OnlineBookDisp;
import org.apache.log4j.Logger;
/**
* @Author j.tommy
* @Date 2016/6/19 0019 上午 4:08
*/
public class ICEBookService extends _OnlineBookDisp implements Service{
public static final Logger log = Logger.getLogger(ICEBookService.class);
private ObjectAdapter _adapter;
@Override
public void bookTick(String name, double price, String content, Current __current) {
log.info("Call bookTick()...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
}
@Override
public void start(String name, Communicator communicator, String[] strings) {
// 创建objectAdapter,这里和service同名
_adapter = communicator.createObjectAdapter(name);
// 传Serant并激活
Ice.Object object = this;
_adapter.add(object,communicator.stringToIdentity(name));
_adapter.activate();
log.info(name + " started.");
}
@Override
public void stop() {
log.info(this._adapter.getName() + " stoped.");
_adapter.destroy();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.hhly.tel.ice.book.service;
import Ice.Communicator;
import Ice.Current;
import Ice.ObjectAdapter;
import IceBox.Service;
import com.hhly.tel.ice.book._SMSServiceDisp;
import org.apache.log4j.Logger;
/**
* @Author j.tommy
* @Date 2016/6/19 0019 上午 4:08
*/
public class ICESMSService extends _SMSServiceDisp implements Service{
public static final Logger log = Logger.getLogger(ICESMSService.class);
private ObjectAdapter _adapter;
@Override
public void start(String name, Communicator communicator, String[] strings) {
// 创建objectAdapter,这里和service同名
_adapter = communicator.createObjectAdapter(name);
// 传Serant并激活
Ice.Object object = this;
_adapter.add(object,communicator.stringToIdentity(name));
_adapter.activate();
log.info(name + " started.");
}
@Override
public void stop() {
log.info(this._adapter.getName() + " stoped.");
_adapter.destroy();
}
@Override
public void sendSMS(String name, double price, String content, Current __current) {
log.info("Call sendSMS()...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
}
}

icebox的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#server properties
# icebox实例的名字
IceBox.InstanceName=MyAppIceBox 1
# =1表示所有的服务使用Icebox中的配置
IceBox.InheritProperties=1
# =1会在icebox启动完毕后打印MyAppIceBox 1 ready
IceBox.PrintServicesReady=MyAppIceBox 1
#IceBox的管理组件,使之能够被远程访问,默认关闭,下面将其绑定到本地9999端口
IceBox.ServiceManager.Endpoints=tcp -p 8989 -h localhost
#performance properties
Ice.ThreadPool.Server.Size=4
Ice.ThreadPool.Server.SizeMax=100
Ice.ThreadPool.Server.SizeWarn=10
Ice.ThreadPool.Client.Size=4
Ice.ThreadPool.Client.SizeMax=100
Ice.ThreadPool.Client.SizeWarn=40
#for system stronger
Ice.ACM.Client=300
Ice.ACM.Server=300
#log and trace
#表明日志存放在日志文件中,否则会打印到控制台。
#Ice.LogFile=iceserv.log
Ice.PrintStackTraces=1
Ice.Trace.Retry=2
Ice.Trace.Network=2
Ice.Trace.ThreadPool=1
Ice.Trace.Locator=2
Ice.Warn.Connections=1
Ice.Warn.Dispatch=1
Ice.Warn.Endpoints=1
#service defined begin
IceBox.Service.OnlineBook=com.hhly.tel.ice.book.service.ICEBookService prop1=1 prop2=2 prop3=3
IceBox.Service.SMSService=com.hhly.tel.ice.book.service.ICESMSService
OnlineBook.Endpoints=tcp -p 9000 -h localhost
SMSService.Endpoints=tcp -p 9001 -h localhost
#service defined end
#server load order
IceBox.LoadOrder=OnlineBook,SMSService
#service share communicator
IceBox.UseSharedCommunicator.OnlineBook=1
IceBox.UseSharedCommunicator.SMSService=1

IceBox.Service.name=entry_point [–key=value] [args]
各个参数的定义:
name定义了service的名字,如上面定了2个Service,一个OnlineBook,一个SMSService.
entry_point是service的完整类名
[–key=value]将会被作为property属性,用于构造该服务的communicator,用来更加精确的控制每个Ice服务的性能调优,这里也可以使用–Ice.Config=xxx.cfg的方式从具体的配置文件加载参数。
IceBox.InheritProperties=1,让所有的ice服务都使用IceBox的配置属性。
[args]作为参数传入start()方法的args参数,作为服务端启动初始化参数。

Ice.MessageSizeMax:做大消息包的字节数
Ice.Trace.Network=1,开启网络事件相关的日志追踪
Ice.Trace.ThreadPool=1,开启线程池事件的日志追踪
Ice.Trace.Locator=1,开启Locator对象的日志追踪

IceBox.UseShardedCommunicator.serviceName=1,实现服务本地调用的优化。如上面的OnlineBook和SMSService,都部署在同一个IceBox中,定义他们使用同一个Communicator对象,实现本地调用的优化。

IceBox.LoadOrder=serv1,serv2,serv3,指定服务的加载顺序,如上面的OnlineBook和SMSService。

启动服务,并启动

1
2
3
4
5
6
7
8
9
10
11
package com.hhly.tel.ice.book.client;
/**
* @Author j.tommy
* @Date 2016/6/19 0019 上午 4:33
*/
public class Server {
public static void main(String[] args) {
IceBox.Server server = new IceBox.Server();
server.main(new String[]{"--Ice.Config=icebox.properties"});
}
}

编写客户端并启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.hhly.tel.ice.book.client;
import com.hhly.tel.ice.book.*;
/**
* @Author j.tommy
* @Date 2016/6/19 0019 上午 4:27
*/
public class Client {
public static void main(String[] args) {
// 调用OnlineBook接口
bookTick(args);
// 调用SMSService接口
sendSMS(args);
}
private static void bookTick(String[] args) {
int status = 0;
Ice.Communicator ic = null;
try {
ic = Ice.Util.initialize(args);
Ice.ObjectPrx base = ic.stringToProxy("OnlineBook:default -p 9000");
OnlineBookPrx onlineBookPrx = OnlineBookPrxHelper.checkedCast(base);
if (onlineBookPrx == null) {
throw new Error("Invalid proxy");
}
onlineBookPrx.bookTick("ICE权威指南",59,"这是一本介绍ICE的书籍。");
} catch (Error error) {
error.printStackTrace();
status = 1;
} finally {
if (ic != null) {
ic.destroy();
}
// System.exit(status);
}
}
private static void sendSMS(String[] args) {
int status = 0;
Ice.Communicator ic = null;
try {
ic = Ice.Util.initialize(args);
Ice.ObjectPrx base = ic.stringToProxy("SMSService:default -p 9001");
SMSServicePrx smsServicePrx = SMSServicePrxHelper.checkedCast(base);
if (smsServicePrx == null) {
throw new Error("Invalid proxy");
}
smsServicePrx.sendSMS("ICE权威指南",59,"这是一本介绍ICE的书籍。");
} catch (Error error) {
error.printStackTrace();
status = 1;
} finally {
if (ic != null) {
ic.destroy();
}
System.exit(status);
}
}
}

ICE Service之间的调用

ICESMSService的实现方法修改如下:

@Override
public void sendSMS(String name, double price, String content, Current __current) {
    if (name.startsWith("book")) {
        Ice.ObjectPrx base = _adapter.getCommunicator().stringToProxy("OnlineBook");
        OnlineBookPrx onlineBookPrx = OnlineBookPrxHelper.checkedCast(base);
        if (null != onlineBookPrx) {
            onlineBookPrx.bookTick(name,price,content);
            log.info("通过短信购买图书!...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
        }
         else {
             throw new Error("Can't find OnlinkBook Service.");
         }
     }
     else {
         log.info("发送短信成功...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
     }
 }

上面的代码表明:如果name以book开头,则内部调用OnlineBookService购买图书。否则就是发送短信。

试验:
客户端代码:

private static void sendSMS(String name,double price,String content,String[] args) {
    int status = 0;
    Ice.Communicator ic = null;
    try {
        ic = Ice.Util.initialize(args);
        Ice.ObjectPrx base = ic.stringToProxy("SMSService:default -p 9001");
        SMSServicePrx smsServicePrx = SMSServicePrxHelper.checkedCast(base);
        if (smsServicePrx == null) {
            throw new Error("Invalid proxy");
         }
         smsServicePrx.sendSMS(name,price,content);
     } catch (Error error) {
         error.printStackTrace();
         status = 1;
     } finally {
         if (ic != null) {
             ic.destroy();
         }
//            System.exit(status);
     }
 }
public static void main(String[] args) {
    // 调用OnlineBook接口
    bookTick(args);
    System.out.println("bookTick(args) Finished");
    // 调用SMSService接口
    sendSMS("book ICE权威指南",59,"这是一本介绍ICE的书籍。",args);
    System.out.println("sendSMS() Finished");
    // 在SMSService中调用OnlineBookService,演示ICE服务之间的调用
    sendSMS("发送短信",59,"这是一本介绍ICE的书籍。",args);
     System.out.println("Send Message Finished.");
 }