一个简单的rpc框架的实现

为了降低开发成本,提升已有系统的利用率,企业往往会构建自己的SOA体系结构,SOA构建的手段有多种,可以通过webservicerestfulrmisocket等等,笔者通过java socket,来构建一个简单的SOA体系结构,以下代码仅供参考。

 

 

1.  需要实现SOA的服务接口

 

package com.chenkangxian.rpc.impl;

/**
 *
 * @Author: chenkangxian
 *
 * @Annotation: 根据key取数据接口
 *
 * @Date:2012-5-13
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 *
 */

public interface DataService {

    String getData(String key);

}

 

2.   接口的实现

 

 

package com.chenkangxian.rpc.impl;

/**
 *
 * @Author: chenkangxian
 *
 * @Annotation: 根据key取数据服务实现
 *
 * @Date:2012-5-13
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 *
 */
public class DataServiceImpl implements DataService {

	public String getData(String key) {
		
        return "this is the data when key = " + key ;
    }

}
 

 

3.  执行代理

 

 

/**
 * 
 */
package com.chenkangxian.rpc.impl;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 * @Author: chenkangxian
 *
 * @Annotation: 执行代理
 *
 * @Date:2012-5-15
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 * 
 */
public class InvocationProxy implements InvocationHandler{

	private String host;
	private int port;

	public InvocationProxy(String host, int port){
		this.host = host;
		this.port = port;
	}

	public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
		Socket socket = new Socket(host, port);
		try {
			ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
			try {
				output.writeUTF(method.getName());
				output.writeObject(method.getParameterTypes());
				output.writeObject(arguments);
				ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
				try {
					Object result = input.readObject();
					if (result instanceof Throwable) {
						throw (Throwable) result;
					}
					return result;
				} finally {
					input.close();
				}
			} finally {
				output.close();
			}
		} finally {
			socket.close();
		}
	}
}

 

4.    服务消费者

 

 

package com.chenkangxian.rpc.impl;

/**
 * @Author: chenkangxian
 *
 * @Annotation: 服务消费者
 *
 * @Date:2012-5-13
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 *
 */
public class RpcConsumer {
    
    public static void main(String[] args) throws Exception {
        DataService service = RpcFramework.refer(DataService.class, "127.0.0.1", 1234);
        for (int i = 0; i < Integer.MAX_VALUE; i ++) {
            String value = service.getData("key_" + i);
            System.out.println(value);
            Thread.sleep(1000);
        }
    }
    
}

 

5.    远程调用框架

 

 

package com.chenkangxian.rpc.impl;

import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @Author: chenkangxian
 *
 * @Annotation: 简单的远程调用框架实现
 *
 * @Date:2012-5-13
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 *
 */
public class RpcFramework {
	
	/**
	 * 暴露服务
	 * 
	 * Author: chenkangxian
	 *
	 * Last Modification Time: 2012-5-15
	 *
	 * @param service 服务实现
	 * @param port 服务端口
	 * @throws Exception
	 */
	public static void export(final Object service, int port) throws Exception {
		if (service == null)
			throw new IllegalArgumentException("service instance == null");
		if (port <= 0 || port > 65535)
			throw new IllegalArgumentException("Invalid port " + port);
		System.out.println("Export service " + service.getClass().getName() + " on port " + port);
		ServerSocket server = new ServerSocket(port);
		for(;;) {
			try {
				final Socket socket = server.accept();
				ThreadPoolHelp.getExecutorInstance().execute(new WorkThread(service, socket));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 引用服务
	 * 
	 * Author: chenkangxian
	 *
	 * Last Modification Time: 2012-5-15
	 *
	 * @param <T> 接口泛型
	 * @param interfaceClass 接口类型
	 * @param host 服务器主机名
	 * @param port 服务器端口
	 * @return 远程服务
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception {
		
		if (interfaceClass == null)
			throw new IllegalArgumentException("Interface class == null");
		if (! interfaceClass.isInterface())
			throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");
		if (host == null || host.length() == 0)
			throw new IllegalArgumentException("Host == null!");
		if (port <= 0 || port > 65535)
			throw new IllegalArgumentException("Invalid port " + port);
		
		System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);
		
		return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationProxy(host,port));
	}

}

 

 

6.    服务提供者

 

 

package com.chenkangxian.rpc.impl;

/**
 * @Author: chenkangxian
 *
 * @Annotation: 服务提供者
 *
 * @Date:2012-5-13
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 *
 */
public class RpcProvider {

    public static void main(String[] args) throws Exception {
        DataService service = new DataServiceImpl();
        RpcFramework.export(service, 1234);
    }

}

 

7.    线程池帮助类

 

 

/**
 * 
 */
package com.chenkangxian.rpc.impl;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: chenkangxian
 *
 * @Annotation:  线程池帮助类
 *
 * @Date:2012-5-15
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 * 
 */
public class ThreadPoolHelp {

	private static ExecutorService executor ;
	
	static{
		executor = Executors.newFixedThreadPool(20);
	}
	
	public static ExecutorService getExecutorInstance(){
		return executor;
	}
}

 

 

8.    工作线程

 

 

/**
 * 
 */
package com.chenkangxian.rpc.impl;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 *
 * @Author: chenkangxian
 *
 * @Annotation: 工作线程
 *
 * @Date:2012-5-15
 *
 * @Copyright: 2012 chenkangxian, All rights reserved.
 * 
 */
public class WorkThread implements Runnable {
	
	private Object service;
	
	private Socket socket;
	
	public WorkThread(Object service,Socket socket){
		this.service = service;
		this.socket = socket;
	}

    @Override
    public void run() {
        try {
            try {
                ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                try {
                    String methodName = input.readUTF();
                    Class<?>[] parameterTypes = (Class<?>[])input.readObject();
                    Object[] arguments = (Object[])input.readObject();
                    ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                    try {
                        Method method = service.getClass().getMethod(methodName, parameterTypes);
                        Object result = method.invoke(service, arguments);
                        output.writeObject(result);
                    } catch (Throwable t) {
                        output.writeObject(t);
                    } finally {
                        output.close();
                    }
                } finally {
                    input.close();
                }
            } finally {
                socket.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
 

 

 

 

猜你喜欢

转载自chenkangxian.iteye.com/blog/1531074