请访问https://git.oschina.net/zhjh256/io-spider获取最新更新。

本部分将介绍使用spider RPC开发分布式应用的客户端和服务端。

spider RPC中间件基于J2SE 8开发,因此需要确保服务器上安装了JDK 8及以上版本,不依赖于任何额外需要独立安装和配置的依赖程序。

注:spider RPC 1.0.1版本之前基于JDK 1.7开发,最后改为了使用JDK  1.8主要是出于公司内部系统对接的考虑,使用了1.8新增的Parameter类,因为内部系统需要解析参数名。

spider RPC中间件的核心设计初衷是像调用本地服务一样调用远程服务,能够灵活的在运行时确定目标服务在哪台服务器,且高效的管理上百台的大规模服务器集群。

依赖jar包引入

spider包括下列依赖包:

com.ld.net.spider.jar

点击下载

spider核心包 <dependency>

<groupId>com.ld.net.spider</groupId>

<artifactId>com.ld.net.spider</artifactId>

<version>1.0.X-SNAPSHOT</version>

</dependency>

com.ld.net.spider.ext.jar

点击下载

Spider扩展包,比如管理、监控spider运行状态,与服务中心交互等等 <dependency>

<groupId>com.ld.net.spider</groupId>

<artifactId>com.ld.net.spider.ext</artifactId>

<version>1.0.X-SNAPSHOT</version>

</dependency>

com.ld.net.spider.sc.client.api.jar

点击下载

服务中心管理模式下,客户端提供的主要管理功能接口 <dependency>

<groupId>com.ld.net.spider</groupId>

<artifactId>com.ld.net.spider.sc.client.api</artifactId>

<version>1.0.X-SNAPSHOT</version>

</dependency>

com.ld.net.spider.sc.center.api.jar

点击下载

服务中心管理模式下,服务中心端提供的主要功能接口 <dependency>

<groupId>com.ld.net.spider</groupId>

<artifactId>com.ld.net.spider.sc.center.api </artifactId>

<version>1.0.X-SNAPSHOT</version>

</dependency>

定义服务接口

开发spider服务的第一步是定义spider服务接口,spider服务以java interface的方式进行定义。本示例涉及POJO定义如下:

package com.medsoft.spider.api;

public class Demo {
private int id;
private String name;
private double bonus;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
} public class DemoReq extends SpiderBizHead {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} package com.medsoft.spider.api; import com.ld.net.remoting.LDParam; public class DemoResp {
private int errorNo;
private String errorInfo;
public int getErrorNo() {
return errorNo;
}
public void setErrorNo(int errorNo) {
this.errorNo = errorNo;
}
public String getErrorInfo() {
return errorInfo;
}
public void setErrorInfo(String errorInfo) {
this.errorInfo = errorInfo;
}
} package com.medsoft.spider.api; import java.util.List;
import java.util.Map; import com.ld.net.spider.meta.SpiderBizHead; public class DemoQuery extends SpiderBizHead {
private Map<String,String> param;
private List<Demo> result; public List<Demo> getResult() {
return result;
}
public void setResult(List<Demo> result) {
this.result = result;
}
public Map<String,String> getParam() {
return param;
}
public void setParam(Map<String,String> param) {
this.param = param;
} public void addParam(String key,String value) {
this.param.put(key, value);
}
}

定义接口:

package com.medsoft.spider.api;

import java.util.List;

import com.ld.net.spider.annotation.Service;
import com.ld.net.spider.annotation.ServiceModule; @ServiceModule
public interface DemoDrpcpService {
@Service(desc = "Drpcp修改", serviceId = "99000011")
public DemoResp opDrpcpService(DemoReq req); @Service(desc = "Drpcp list查询", serviceId = "99000012")
public List<DemoResp> queryDrpcpService(DemoReq req); @Service(desc = "Drpcp分页查询", serviceId = "99000002")
public DemoQuery queryDrpcpService1(DemoQuery req); @Service(desc = "调用其他MS", serviceId = "99000003")
public String callAS(DemoQuery req);
}

@ ServiceModule标识接口DemoDrpcpService为spider服务模块,@Service定义了具体的服务。

需要注意的是,spider运行时要求所有参数必须通过单个DTO进行传递,否则在启动时会出错而终止,这更多的出于服务管理的需要而非技术的限制或性能的下降。

服务端开发

spider服务的实现和标准的j2ee开发一样,创建一个标准的java web工程,只要定义java类实现服务接口即可,没有任何额外的侵入性。

package com.medsoft.spider.server;

import java.util.ArrayList;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.ld.net.base.utils.JsonUtils;
import com.ld.net.spider.exception.SpiderException;
import com.medsoft.spider.api.DemoDrpcpService;
import com.medsoft.spider.api.DemoQuery;
import com.medsoft.spider.api.DemoReq;
import com.medsoft.spider.api.DemoResp;
import com.medsoft.spider.other.api.OtherService; @Service
public class DemoDrpcpServiceImpl implements DemoDrpcpService { @Autowired
private OtherService otherService; @Override
public DemoResp opDrpcpService(DemoReq req) {
System.out.println("接收到spider调用请求: " + JsonUtils.toJson(req));
return new DemoResp();
} @Override
public DemoQuery queryDrpcpService1(DemoQuery req) {
System.out.println("接收到spider调用请求: " + JsonUtils.toJson(req));
return new DemoQuery();
} @Override
public String callAS(DemoQuery req) {
System.out.println("调用其他系统的AS");
try {
return otherService.doAs(req);
} catch (SpiderException e) {
throw e;
}
} @Override
public List<DemoResp> queryDrpcpService(DemoReq req) {
List<DemoResp> list = new ArrayList<DemoResp>();
DemoResp e1 = new DemoResp();
DemoResp e2 = new DemoResp();
list.add(e1);
list.add(e2);
return list;
}
}

如上所示,实现非常简单,没有任何spider侵入性,故不再重复讲解。

需要注意的是,上述红色字体的OtherService,该服务为标准Spring Bean服务或者微服务MS或其它子系统提供的公用业务服务,比如查询账户信息,视具体而定。

客户端开发

客户端调用spider服务在开发上和调用标准的本地spring bean服务完全相同,创建一个标准的java web工程,只要设置目标服务自动注入就可以直接使用了,如下所示:

@Controller
public class IndexAction {
@Autowired
private DemoDrpcpService demoDrpcpService; @RequestMapping(value="/to_pnp2_cnp1.html",method=RequestMethod.GET)
public @ResponseBody String indexV(Model model,HttpServletRequest request){
DemoQuery req = new DemoQuery();
DemoReq param = new DemoReq();
req.setAppVersion("v1.1");
req.setSystemId("02");
req.setCompanyId("100001");
param.setId(8888);
param.setName("zhangsan");
return JsonUtils.toJson(demoDrpcpService.queryDrpcpService1(req));
}
}
直接通过功能号调用spider服务

除了上述通过注入接口方式调用spider服务外,spider运行时还支持直接通过功能号的方式调用,如下所示:

    DemoReq param = new DemoReq();
param.setId(8888);
param.setName("zhangsan");
param.setCompanyId(companyId);
param.setSystemId(systemId);
ServiceDefinition service = ServiceDefinitionContainer.getService("99000011");
try {
return (DemoResp) service.getMethod().invoke(BeanManagerHelper.getBean(service.getClz()), param);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}

两种方式的调用效果相同。

接口包与实现包的部署

使用Spider开发的分布式系统最简单的情况下通常具有如下的部署结构:

在复杂的生产部署中,其部署结构可能会异常复杂,如下所示:

本示例中,我们以简单的客户端/服务端为例介绍包的部署与配置文件的设置。

spider客户端只需要放置定义服务接口的jar或class即可。

spider服务端需要同时放置定义服务接口的jar或class,和服务实现。一般来说,这两者都打包在jar中而非分散的class会比较合理。

Spider配置

Spider包含一个配置文件,名称为spider.xml,可以修改,具体位置可参见《spider概要设计-配置文件一节》,目前支持三种配置文件指定方式,在标准的maven工程下,建议将其放在src/main/resources下,作为标准配置文件的一部分。

客户端spider.xml示例
<?xml version="1.0" encoding="UTF-8"?>
<spider>
<nodeName value="ANB" cloud="false" role="production"
serviceCenter="0.0.0.0" appVersion="" charset="GBK" />
<plugins>
<plugin pluginId="spider.localService" serviceTimeout="10000"
zlibCompress="false" encrypt="false" anonymous="true"
serviceProxyPackage="com.medsoft.spider.api">
<server enable="false" port="7070" reliable="false"
threadCount="200" serviceExportPackage="" />
</plugin>
<plugin pluginId="spider.channel">
<cluster clusterName="CNB-1" connectionSize="1">
<workNode address="127.0.0.1" port="18021" />
</cluster>
</plugin>
<plugin pluginId="spider.filter">
</plugin>
</plugins>
<routeItems>
<routeItem serviceId="99*" clusterName="CNB-1" />
<!-- <routeItem serviceId="*" appVersion="" subSystemId=""
systemId="" companyId="" clusterName="spider-server" /> -->
</routeItems>
</spider>

上述配置中,红色部分是与客户端直接相关的配置。

服务端spider.xml示例
<?xml version="1.0" encoding="UTF-8"?>
<spider>
<nodeName value="MSNP-1" cloud="false" role="production"
serviceCenter="0.0.0.0" appVersion="" serviceDefineType="spider" needLdPackAdapter="false" charset="GBK"/>
<plugins>
<plugin pluginId="spider.localService" serviceTimeout="10000"
zlibCompress="false" encrypt="false" anonymous="true"
serviceProxyPackage="">
<server enable="true" port="18051" reliable="false"
threadCount="200" serviceExportPackage="com.medsoft.spider.api" />
</plugin>
<plugin pluginId="spider.channel">
</plugin>
<plugin pluginId="spider.filter">
</plugin>
</plugins>
<routeItems>
<routeItem serviceId="*" clusterName="spider.localService" />
<!-- <routeItem serviceId="*" appVersion="" subSystemId=""
systemId="" companyId="" clusterName="spider-server" /> -->
</routeItems>
</spider>

上述配置中,红色部分是与客户端直接相关的配置。

服务端配置注意事项

spider启动时会进行下列自检操作:

1、在/tmp/spider/下检查是否存在${nodeName}.pid文件,如果存在,则说明本服务器上存在同名已启动spider实例,不允许启动;

2、运行服务器模式时,检查本节点spider.xml中定义的服务器端口号是否已经被占用,如果已经被占用,则提示端口号已经被占用,不允许启动;

运行方式

当前版本spider支持运行于标准java应用程序和web容器下两种模式,他们提供完全相同的核心服务。在运行于标准java程序模式下时,spider提供的RESTFUL管理控制台和API将不可用。

web.xml配置

客户端和服务端的web.xml配置要求相同,如不需要启用web监控,只需要包含如下即可:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spider-base-service.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如需启用web监控,则还需要包含如下:
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spider-base-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

启动运行

上述步骤均完成后,就可以启动spider服务端和客户端进行验证了。Spider服务端和客户端的启动顺序无关紧要,spider运行时会每隔指定间隔自动进行检测并尝试建立断开和尚未建立的连接。

spider RPC入门指南的更多相关文章

  1. spider RPC开发指南

    协议与兼容性 spider使用java语言开发,使用Spring作为IoC容器,采用TCP/IP协议,在此基础上,结合SaaS系统模式的特性进行针对性和重点设计,以更加灵活和高效的满足多租户系统.高可 ...

  2. spider RPC框架的需求来源与特性介绍(一)

    spider RPC 特性介绍 spider RPC 性能测试 spider RPC 入门指南 spider RPC 配置文件参考 spider RPC 开发指南 spider RPC 安全性 spi ...

  3. Flume NG Getting Started(Flume NG 新手入门指南)

    Flume NG Getting Started(Flume NG 新手入门指南)翻译 新手入门 Flume NG是什么? 有什么改变? 获得Flume NG 从源码构建 配置 flume-ng全局选 ...

  4. Web API 入门指南 - 闲话安全

    Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患.相关的防御技巧以及Web AP ...

  5. Vue.js 入门指南之“前传”(含sublime text 3 配置)

    题记:关注Vue.js 很久了,但就是没有动手写过一行代码,今天准备入手,却发现自己比菜鸟还菜,于是四方寻找大牛指点,才终于找到了入门的“入门”,就算是“入门指南”的“前传”吧.此文献给跟我一样“白痴 ...

  6. yii2实战教程之新手入门指南-简单博客管理系统

    作者:白狼 出处:http://www.manks.top/document/easy_blog_manage_system.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文 ...

  7. 【翻译】Fluent NHibernate介绍和入门指南

    英文原文地址:https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started 翻译原文地址:http://www.cnblogs ...

  8. ASP.NET MVC 5 入门指南汇总

    经过前一段时间的翻译和编辑,我们陆续发出12篇ASP.NET MVC 5的入门文章.其中大部分翻译自ASP.NET MVC 5 官方教程,由于本系列文章言简意赅,篇幅适中,从一个web网站示例开始讲解 ...

  9. 一起学微软Power BI系列-官方文档-入门指南(1)Power BI初步介绍

    我们在前一篇文章微软新神器-Power BI,一个简单易用,还用得起的BI产品中,我们初步介绍了Power BI的基本知识.由于Power BI是去年开始微软新发布的一个产品,虽然已经可以企业级应用, ...

随机推荐

  1. C# 正则表达式大全

    文章导读 正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串.正则表达式无疑是处理文本最有力的工具,而.NET提供的Regex类实现了验证正则表达式的方法.Regex 类表示不可变(只读)的 ...

  2. WebApi接口 - 如何在应用中调用webapi接口

    很高兴能再次和大家分享webapi接口的相关文章,本篇将要讲解的是如何在应用中调用webapi接口:对于大部分做内部管理系统及类似系统的朋友来说很少会去调用别人的接口,因此可能在这方面存在一些困惑,希 ...

  3. js刷新页面方法大全

    如何实现刷新当前页面呢?借助js你将无所不能. 1,reload 方法,该方法强迫浏览器刷新当前页面.语法:location.reload([bForceGet])   参数: bForceGet, ...

  4. 流程表单中js如何清空SheetUser控件数据?

    昨天有人问我js怎么清空.我试了试,发现简单的赋给他空值,并没有用.只能给他赋一个真实存在的值才有用.于是跟踪了一下他的删除按钮. 效果如下 使用场景:可以根据字段的不同类别变更人员. js代码如下, ...

  5. mono-3.4.0 源码安装时出现的问题 [do-install] Error 2 [install-pcl-targets] Error 1 解决方法

    Mono 3.4修复了很多bug,继续加强稳定性和性能(其实Mono 3.2.8 已经很稳定,性能也很好了),但是从http://download.mono-project.com/sources/m ...

  6. 在CentOS上构建.net自动化编译环境

             我们知道在Windows上我们很容易构建于MSBuild的自动化编译环境,那么在CentOS也是可以的,主要是需要Mono. 在这儿我们选择Jenkins+Gitlab+Mono在C ...

  7. ubuntu+mono+jexus 搭建.net的web平台 实现.net跨平台

    准备工作: vmware 用来安装 ubuntu 下载地址:VMware-workstation-9.0.1-894247.exe.tar 注册码: 1A4P8-DMK0N-FZ431-7K8NH-2 ...

  8. AutoMapper(五)

    返回总目录 Dynamic和ExpandoObject映射 AutoMapper不用任何配置就可以从dynamic(动态)对象映射或映射到dynamic对象. namespace FifthAutoM ...

  9. ucos实时操作系统学习笔记——操作系统在STM32的移植

    使用ucos实时操作系统是在上学的时候,导师科研项目中.那时候就是网上找到操作系统移植教程以及应用教程依葫芦画瓢,功能实现也就罢了,没有很深入的去研究过这个东西.后来工作了,闲来无聊就研究了一下这个只 ...

  10. TDD原则

    TDD 介绍 测试驱动开发,或者叫 TDD,是一个敏捷方法,通过确保在代码是先前手动编写测试用 例,用测试来驱动开发,从而翻转开发生命周期(它不只是作为一种校验工具). TDD 的原则很简单的: 只有 ...