2.5.16 工人服务化模式应用示例

前面2.1.8节中,我们详细介绍了工人服务化模式,这里我们演示建立一个如下demo:输入一个名字,返回一个hello xx的服务demo,我们看到大部分服务化产品的上手程序都是类似这样的sayHello。设计思路如下:

❏ CtorClient:建立了一个工头客户端,在服务化运用中,包工头已经失去了在并行计算里的名称含义,它变成了一个可以获取多种类型服务,调用多种类型服务,获取调用结果的综合性服务客户端。

我们可以看到,CtorClient定义了一个sayHello的服务接口,这个服务接口是面向用户的,sayHello服务的实现是调用了giveTask,而在giveTask里面则是通过获取工人服务类型,调用doTaskBatch获得结果,然后将结果返回给sayHello。

sayHello的实现实际上是将用户的String name输入包装为工人通用服务doTask的输入,再请求远程工人的服务实现,最后将结果转换为String返回给用户。

❏ ServiceWorker:建立了一个工人服务,需要在配置文件config.xml的工人模块部分,设置为<SERVICE>true</SERVICE>,这样保证工人可以对外提供多个客户端的请求服务。在工人的doTask里面实现了sayHello服务的逻辑,就是获取输入参数后,加上hello返回。

❏ ClientMain:为了模拟多个工头客户端请求服务,我们使用了前面介绍的BeanContext.tryStart启动两个进程去同时调用sayHello服务,并将各自的日志结果输出到相应文件。

运行步骤如下:

1)编译demo的java类:

  1. Javac classpath fourinone.jar; *.java

2)启动ParkServerDemo(它的IP端口已经在配置文件的PARK部分的SERVERS指定):

  1. Java classpath fourinone.jar; ParkServerDemo

3)运行ServiceWorker(传入端口号参数,这里启动一个工人即可,代表只有一个服务地址):

  1. Java classpath fourinone.jar; ServiceWorker 2008

4)运行ClientMain(它内部会启动2个工头客户端访问服务):

  1. Java classpath fourinone.jar; ClientMain

下面是demo源码:

  1. // ParkServerDemo
  2. import com.fourinone.BeanContext;
  3. public class ParkServerDemo{
  4. public static void main(String[] args){
  5. BeanContext.startPark();
  6. }
  7. }
  8.  
  9. // ServiceWorker
  10. import com.fourinone.MigrantWorker;
  11. import com.fourinone.WareHouse;
  12.  
  13. public class ServiceWorker extends MigrantWorker
  14. {
  15. public WareHouse doTask(WareHouse inhouse)
  16. {
  17. //取出参数的值
  18. String inputstring = inhouse.getString("InputString");
  19. //收到服务请求后,返回hello
  20. return new WareHouse("Result", inputstring+",hello");
  21. }
  22.  
  23. public static void main(String[] args)
  24. {
  25. ServiceWorker mw = new ServiceWorker();
  26. //启动服务,<SERVICE>true</SERVICE>
  27. mw.waitWorking("localhost",Integer.parseInt(args[0]),"HelloService");
  28. }
  29. }
  30.  
  31. // CtorClient
  32. public class CtorClient extends Contractor
  33. {
  34. public String sayHello(String name)
  35. {
  36. //封装输入参数InputString,然后实际调用通用服务接口
  37. WareHouse result = giveTask(new WareHouse("InputString",name));
  38. //返回服务请求的结果
  39. return result.getString("Result");
  40. }
  41.  
  42. public WareHouse giveTask(WareHouse inhouse)
  43. {
  44. //获取提供Hello服务的地址,这里假设只有一个,但可以是多个
  45. WorkerLocal[] wks = getWaitingWorkers("HelloService");
  46. System.out.println("wks.length:"+wks.length);
  47.  
  48. //请求服务并传入InputString参数,然后等待结果完成后返回
  49. WareHouse[] result = doTaskBatch(wks, inhouse);
  50.  
  51. return result[0];
  52. }
  53.  
  54. public static void main(String[] args)
  55. {
  56. CtorClient a = new CtorClient();
  57. String serviceResult = a.sayHello(args[0]);
  58. System.out.println(serviceResult);
  59. a.exit();
  60. }
  61. }
  62.  
  63. // ClientMain
  64. import com.fourinone.StartResult;
  65. import com.fourinone.BeanContext;
  66.  
  67. public class ClientMain
  68. {
  69. public static void main(String[] args)
  70. {
  71. //同时启动2个客户端调用Hello服务,将结果输出到相应日志
  72. StartResult<Integer> ctor1 = BeanContext.tryStart("java","-cp","fourinone.
  73. ??jar;","CtorClient","client1");
  74. ctor1.print("log/ctor1.log");
  75. StartResult<Integer> ctor2 = BeanContext.tryStart("java","-cp","fourinone.
  76. ??jar;","CtorClient","client2");
  77. ctor2.print("log/ctor2.log");
  78. }
  79. }