论坛首页 编程语言技术论坛

Spring集成Thrift--Server AND Client

浏览 1494 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-09-04  

Thrift网上有N多教程,不再赘述,这里搭建的是WEB项目,使用了spring,所以尽量使用了基于配置的方式。

一。server端

本着少些代码,配置优先的原则,在server端引入代理类,如下:

ThriftServerProxy:使用了反射

 

public class ThriftServerProxy {
		
	private static Logger logger = Logger.getLogger(ThriftServerStartListener.class);
	private int port;// 端口
	private String serviceInterface;// 实现类接口	
	private Object serviceImplObject;//实现类

	set and get ……………………
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void start() {
	new Thread() {
	public void run() {

		try {
		TServerSocket serverTransport = new TServerSocket(getPort());		
		Class Processor = Class.forName(getServiceInterface()+"$Processor");
		Class Iface = Class.forName(getServiceInterface()+"$Iface");				Constructor con = Processor.getConstructor(Iface);
		TProcessor processor = (TProcessor)con.newInstance(serviceImplObject);
		Factory protFactory = new TBinaryProtocol.Factory(true,true);
		TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport);
		args.protocolFactory(protFactory);
					
		args.processor(processor);
		TServer server = new TThreadPoolServer(args);
		logger.info("Starting server on port "+getPort()+" ...");
		server.serve();

		} catch (TTransportException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		}
		}.start();
	}
}

 applicationContext-thrift.xml:

 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	……………………………………………………

	<description>thrift服务</description>
	<!-- 声明多个server,并将其关联到该list中,以便监听器自动启动 -->
	<util:list id="thriftServerList">
		<ref bean="userProxy01" />
		<ref bean="userProxy02" />
	</util:list>
	
	<bean id="userProxy01" class="thrift.proxy.ThriftServerProxy">
		<property name="port" value="7911"/>
		<property name="serviceInterface" value="thrift.service.UserService"/>
		<property name="serviceImplObject" ref="userServiceImpl"/>	
	</bean>
		
	<bean id="userProxy02" class="thrift.proxy.ThriftServerProxy">
		<property name="port" value="7910"/>
		<property name="serviceInterface" value="thrift.service.UserService"/>
		<property name="serviceImplObject" ref="userServiceImpl"/>	
	</bean>
		
</beans>

 使用监听器启动全部服务:

 

ThriftServerStartListener:

 

public class ThriftServerStartListener implements ServletContextListener{
	private static Logger logger = Logger.getLogger(UserServiceImpl.class);
	

	@Override
	public void contextDestroyed(ServletContextEvent event) {
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public void contextInitialized(ServletContextEvent event) {
		//启动SETUP SEERVER
		try {
			ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
			
			List<ThriftServerProxy> list = ((List<ThriftServerProxy>) context.getBean("thriftServerList"));
			if(list!=null&&list.size()>0){
				for(ThriftServerProxy userProxy:list){
					userProxy.start();
				}
			}

			logger.info("Thrift Server监听接口启动。。。。。。。。。。。");
		} catch (Exception e) {
			logger.error("Thrift Server监听接口启动错误", e);
			e.printStackTrace();
		}
	}

}

 二。client端

 

client使用链接池管理链接,同时对客户端使用代理,spring配置如下:

applicationContext-thrift.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"

    ……………………………………………………
	<description>thrift客户端</description>
	
	<context:property-placeholder
		location="classpath:config/properties/thrift.properties" />
		
	<!-- 连接池,管理器,客户端代理,3个一组 -->
	<!-- thrift连接池配置7911 -->
	<bean id="connectionProvider01" class="thrift.common.ConnectionProviderImpl">
		<property name="serviceIP" value="${thrift.ens.ip01}" />
		<property name="servicePort" value="${thrift.ens.port01}" />
		<property name="maxActive" value="${thrift.ens.maxActive}" />
		<property name="maxIdle" value="${thrift.ens.maxIdle}" />
		<property name="testOnBorrow" value="${thrift.ens.testOnBorrow}" />
		<property name="testOnReturn" value="${thrift.ens.testOnReturn}" />
		<property name="testWhileIdle" value="${thrift.ens.testWhileIdle}" />
		<property name="conTimeOut" value="${thrift.ens.conTimeOut}" />
	</bean>
	<!-- thrift连接管理配置7911 -->
	<bean id="connectionManager01" class="thrift.common.ConnectionManager">
		<property name="connectionProvider" ref="connectionProvider01" />
	</bean>
	
	<bean id="userClient01" class="thrift.proxy.ThriftClientProxy">
		<property name="serviceInterface" value="thrift.service.UserService" />
		<property name="connectionManager" ref="connectionManager01" />		
	</bean>
	
	<!-- thrift连接池配置7910 -->
	<bean id="connectionProvider02" class="thrift.common.ConnectionProviderImpl">
		<property name="serviceIP" value="${thrift.ens.ip02}" />
		<property name="servicePort" value="${thrift.ens.port02}" />
		<property name="maxActive" value="${thrift.ens.maxActive}" />
		<property name="maxIdle" value="${thrift.ens.maxIdle}" />
		<property name="testOnBorrow" value="${thrift.ens.testOnBorrow}" />
		<property name="testOnReturn" value="${thrift.ens.testOnReturn}" />
		<property name="testWhileIdle" value="${thrift.ens.testWhileIdle}" />
		<property name="conTimeOut" value="${thrift.ens.conTimeOut}" />
	</bean>
	<!-- thrift连接管理配置 7910-->
	<bean id="connectionManager02" class="thrift.common.ConnectionManager">
		<property name="connectionProvider" ref="connectionProvider02" />
	</bean>
	
	
	
	<bean id="userClient02" class="thrift.proxy.ThriftClientProxy">
		<property name="serviceInterface" value="thrift.service.UserService" />
		<property name="connectionManager" ref="connectionManager02" />		
	</bean>
	
</beans>

 

 

 

ThriftClientProxy:

 

public class ThriftClientProxy {

	private String serviceInterface;
	private ConnectionManager connectionManager;
        set and get……………………
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Object getClient() {
		Object object = null;
		try {
			TTransport transport = connectionManager.getSocket();

			TProtocol protocol = new TBinaryProtocol(transport);
			Class client = Class.forName(getServiceInterface() + "$Client");

			Constructor con = client.getConstructor(TProtocol.class);
			object = con.newInstance(protocol);

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return object;
	}
}

 客户端调用,这里使用一个controller:

 

 

@Controller
public class IndexController {
	
	@Resource(name="userClient01")
	private ThriftClientProxy client01;
	
	@Resource(name="userClient02")
	private ThriftClientProxy client02;

	@RequestMapping("/index.do")
	public String handleIndex(Model model) {
		UserService.Client client_01 = (UserService.Client)(client01.getClient());
		UserService.Client client_02 = (UserService.Client)(client02.getClient());
		String name;
		try {
			client_01.getUser("zhangsan");
			name = client_02.getUserName("zhaosi", 100);
			model.addAttribute("userName", name);
		} catch (TException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return "index";
	}
	
}

连接池部分参考了如下内容:http://wenku.baidu.com/view/d0e91021aaea998fcc220e3d.html 

代码详见附件。

 

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics