Thrift 使用以及使用动态代理透明化调用
来源:互联网 发布:淘宝的所在地怎么修改 编辑:程序博客网 时间:2024/06/01 09:33
Thrift 使用以及使用动态代理透明化调用
github项目地址:
github项目地址
本文介绍的是多服务的调用与使用动态代理进行透明化调用
因为每次调用方法时都要对transport (io/socket 资源) 进行开启关闭,所以就想设计client 代理起来,然后在前后添加 transport 的open 和 close() (finally);
当然之后在研究自己写一款thrift的连接池,因为io资源不一定每次都需要创建!!!
thrift 版本号 0.10.0
thrift 文件:
IThriftInfoTestService.thriftIThriftTestService.thrift
IThriftInfoTestService.thrift
代码:
namespace java com.java.thrift.servicenamespace cpp com.java.thrift.servicenamespace perl com.java.thrift.servicenamespace php com.java.thrift.serviceservice IThriftInfoTestService { string showInfoData(1:string name,2:bool b2,3:map<string,string> m2)}
IThriftTestService.thrift
代码:
namespace java com.java.thrift.servicenamespace cpp com.java.thrift.servicenamespace perl com.java.thrift.servicenamespace php com.java.thrift.serviceservice IThriftTestService { string showThriftResult(1:string name,2:bool b2,3:map<string,string> m2)}
provider
spring配置文件 spring-thrift.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <!-- 两个thrift 服务的实现类 --> <bean id="thriftInfoTestServiceTarget" class="com.java.core.rpc.thrift.service.impl.ThriftInfoTestServiceImpl" ></bean> <bean id="thriftTestServiceTarget" class="com.java.core.rpc.thrift.service.impl.ThriftTestServiceImpl" ></bean> <!-- Processor调用过程工厂,创建多服务类的工厂类 --> <bean id="thriftProcessorFactory" class="com.java.core.rpc.thrift.supports.ThriftProcessorFactory" init-method="convertTargetToTProcessor" > <property name="targets" > <list > <ref bean="thriftInfoTestServiceTarget"/> <ref bean="thriftTestServiceTarget"/> </list> </property> </bean> <!-- thrift 的provider的启动类 --> <bean class="com.java.core.rpc.thrift.provider.AppThriftServer" init-method="initThriftServer" ></bean></beans>
ThriftInfoTestServiceImpl.java
package com.java.core.rpc.thrift.service.impl;import java.util.Map;import org.apache.thrift.TException;import com.alibaba.fastjson.JSONObject;import com.java.core.rpc.thrift.service.IThriftInfoTestService;public class ThriftInfoTestServiceImpl implements IThriftInfoTestService.Iface { @Override public String showInfoData(String name, boolean success, Map<String, String> map) throws TException { // TODO Auto-generated method stub System.out.println(" ThriftInfoTestServiceImpl doing ...showInfoData()... "); System.out.println(" map : "+ JSONObject.toJSONString(map)); System.out.println(" success : "+ success); System.out.println(" name : "+ name); String result = name +" time : " + System.currentTimeMillis(); return result; }}
ThriftTestServiceImpl.java 代码就不贴了。都一样
ThriftProcessorFactory.java processor工厂类
public class ThriftProcessorFactory { private final static String IFACE_NAME="$Iface"; private final static String PROCESS_NAME="$Processor"; private List<Object> targets; private Map<String, TProcessor> processors; private TMultiplexedProcessor multiplexedProcessor; public TMultiplexedProcessor getMultiplexedProcessor() { return multiplexedProcessor; } public void setMultiplexedProcessor(TMultiplexedProcessor multiplexedProcessor) { this.multiplexedProcessor = multiplexedProcessor; } public ThriftProcessorFactory() { super(); // TODO Auto-generated constructor stub } public Map<String, TProcessor> getProcessors() { return processors; } public void setProcessors(Map<String, TProcessor> processors) { this.processors = processors; } public List<Object> getTargets() { return targets; } public void setTargets(List<Object> targets) { this.targets = targets; } /** * 将实现类封装成TProcessor类的集合 * */ public void convertTargetToTProcessor(){ if (targets.isEmpty()) { return ; } processors = new HashMap<String, TProcessor>(); try { for (Object target : targets ) { Class iface= target.getClass().getInterfaces()[0]; String ifaceName =iface.getName(); String serviceName = ifaceName.substring(0, ifaceName.lastIndexOf(IFACE_NAME)); Class processorClazz = Class.forName(serviceName.concat(PROCESS_NAME)); Object processorObj = processorClazz.getConstructor(iface).newInstance(iface.cast(target)); if (processorObj instanceof TProcessor) { TProcessor processor = (TProcessor) processorObj; processors.put(serviceName, processor); } } } catch (Exception e) { e.printStackTrace(); } initMultiplexedProcessor(); } /** * 初始化多服务调用过程 TMultiplexedProcessor * 并且注册服务 */ private void initMultiplexedProcessor(){ if (processors.isEmpty()) { return ; } multiplexedProcessor = new TMultiplexedProcessor(); Set<String> serviceNames = processors.keySet(); for (String serviceName : serviceNames) { if (!processors.containsKey(serviceName)) { continue; } multiplexedProcessor.registerProcessor(serviceName, processors.get(serviceName)); } }}
AppThriftServer.java 重点,服务启动
public class AppThriftServer implements ApplicationContextAware { /**线程池**/ private static ExecutorService executorService; // ApplicationContextAware 可以调用spring 生命周期获取上下文 private static ApplicationContext context; public AppThriftServer() { super(); // TODO Auto-generated constructor stub executorService = Executors.newSingleThreadExecutor(); } public void initThriftServer(){ executorService.execute(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println(" ThriftServer start ing ...."); TNonblockingServerSocket transport = null; try { //非阻塞 ServerSocket transport =new TNonblockingServerSocket(new InetSocketAddress(29999)); // 获取 TProcessor ThriftProcessorFactory thriftProcessorFactory=context.getBean(ThriftProcessorFactory.class); TProcessor processor =thriftProcessorFactory.getProcessor(); // nio selectorThreads处理io, workerThreads 处理服务调用过程 TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(transport); args.processor(processor); // customer也要TFramedTransport对应 否则报错 args.transportFactory(new TFramedTransport.Factory()); //二进制协议 args.protocolFactory(new TBinaryProtocol.Factory()); TThreadedSelectorServer server =new TThreadedSelectorServer(args); server.serve(); } catch (Exception e) { e.printStackTrace(); } finally { if (transport != null) { transport.close(); } } } }); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub context=applicationContext; }}
接着启动项目,服务端便开始监听;
接着是 customer 客户端
调用主体
public class App { private static ApplicationContext applicationContext; public static void main( String[] args ) { System.out.println( "Hello World!" ); init(); final TestService testService=applicationContext.getBean(TestService.class); for (int i=0 ;i<10 ;i++) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub testService.doThriftTest(); } }).start(); } } public static void init(){ applicationContext = new FileSystemXmlApplicationContext("/resources/applicationContext.xml"); }}
TestService.java 中的 doThriftTest() 方法
ThriftServiceProxy 类的静态方法 getThriftClient() 获取接口类实例,在 doThriftTest()方法中是透明化的直接调用
public void doThriftTest(){ //运用动态代理 使thrift 接口透明化调用 IThriftInfoTestService.Iface client =ThriftServiceProxy.getThriftClient(IThriftInfoTestService.Iface.class); Map<String, String> map =new HashMap<String, String>(); map.put("name", "庄杰森"); map.put("IThriftInfoTestService", "client"); map.put("content", "thrift 的 rpc 调用"); String name = "zhuangjiesen ...IThriftInfoTestService doing..."; try { client.showInfoData(name, true, map); } catch (TException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
ThriftServiceProxy.java
可以链接 jdk动态代理
public class ThriftServiceProxy { //client缓存 private static ConcurrentHashMap<String,Object> thriftClientCache; public static <T> T getThriftClient(Class<T> clazz){ if (!clazz.isInterface()) { throw new RuntimeException("类型错误"); } if (thriftClientCache == null) { thriftClientCache = new ConcurrentHashMap<String,Object>(); } T client =null; String cacheKey = clazz.getName(); if (thriftClientCache.containsKey(cacheKey)) { client=(T)thriftClientCache.get(cacheKey); } else { //运用jdk代理方式实现接口类的方法,并且调用 同时 transport 资源通过代理进行close与open 简化代码-->类比事务实现 ThriftServiceProxyInvocation proxyInvocation =new ThriftServiceProxyInvocation(); proxyInvocation.setIfaceClazz(clazz); client = (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{ clazz }, proxyInvocation); if (client != null) { thriftClientCache.put(cacheKey, client); } } return client; }}
ThriftServiceProxyInvocation.java 重点类
初学的因为每次调用方法时都要对transport (io资源) 进行开启关闭,所以就想设计将io资源代理起来可以直接透明调用;此处还用了反射方法
之后研究连接池时,也需要用到动态代理;
public class ThriftServiceProxyInvocation implements InvocationHandler { private final static String IFACE_NAME="$Iface"; private final static String CLIENT_NAME="$Client"; private Class ifaceClazz; public Class getIfaceClazz() { return ifaceClazz; } public void setIfaceClazz(Class ifaceClazz) { this.ifaceClazz = ifaceClazz; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println(" ThriftServiceProxyInvocation invoke doing before ...."); if (ifaceClazz == null) { return null; } TTransport transport = null; Object result = null; try { // 设置调用的服务地址为本地,端口 transport = new TSocket("127.0.0.1", 29999); TFramedTransport framedTransport =new TFramedTransport(transport); TBinaryProtocol binaryProtocol =new TBinaryProtocol(framedTransport); TMultiplexedProtocol multiplexedProtocol =new TMultiplexedProtocol(binaryProtocol, IThriftInfoTestService.class.getName()); transport.open(); String ifaceName =ifaceClazz.getName(); String className = ifaceName.substring(0, ifaceName.lastIndexOf(IFACE_NAME)); String clientName = className.concat(CLIENT_NAME); Class clientClazz = Class.forName(clientName); //构造方法实例化 对应 Hello.Client client = new Hello.Client(protocol); Object clientInstance= clientClazz.getConstructor(TProtocol.class).newInstance(multiplexedProtocol); result=method.invoke(clientInstance, args); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { if (transport != null) { transport.close(); } } System.out.println(" ThriftServiceProxyInvocation invoke doing after ...."); return result; }}
因为是rpc 框架,又看了dubbo 框架的实现,所有这个thrift 还可以进行根据业务深度的封装(注册中心,多服务端,多客户端,monitor..等)
0 0
- Thrift 使用以及使用动态代理透明化调用
- Java静态代理以及动态代理使用详解
- Thrift动态代理客户端
- thrift 简单安装以及rpc使用心得
- HBase Thrift 使用以及Thriftserver 分析
- 动态代理的使用以及其实现机制
- 动态代理使用以及Proxy的内部实现
- 详解java动态代理机制以及使用场景(一)
- 使用DBUtils、动态代理以及注解实现事务控制
- WCF透明代理类,动态调用,支持async-awai
- WCF透明代理类,动态调用,支持async/await
- thrift使用
- Thrift使用
- 使用动态代理,提高工作效率
- Spring动态代理使用
- 为何使用动态代理
- 动态代理使用
- 动态代理的使用
- 计算数学表达式
- Linux的远程连接
- mysql
- Spring并发访问的线程安全性问题(高度总结)
- N元语言模型
- Thrift 使用以及使用动态代理透明化调用
- Compiling PCL for android
- java中,什么是封装,继承,多态和抽象,好处与用法
- SpringMVC实现局部刷新DIV
- Android进阶之路
- Student management system
- 大数据集群机房事项:
- 今天进行了cvte的一面,感觉特糟糕,对自己五星差评,以下为总结
- java实现合并排序算法