Thrift和Spring集成

1.服务端通过TMultiplexedProcessor同时暴露多个服务

/**
 * Thrift通用服务启动类 可以和spring集成
 */
public class CommonServerDemo {

    private int port;

    private Map<String, Object> exposedServerMap;

    public CommonServerDemo(int port, Map<String, Object> exposedServerMap) {
        this.port = port;
        this.exposedServerMap = exposedServerMap;
    }

    public void start() {
        try {
            TNonblockingServerTransport socket = new TNonblockingServerSocket(port);

            TMultiplexedProcessor mp = new TMultiplexedProcessor();

            //同时暴露多个服务
            for (Map.Entry<String, Object> entry : exposedServerMap.entrySet()) {
                String serviceInterface = entry.getKey();
                Class<?> processorClass = Class.forName(serviceInterface + "$Processor");
                Class<?> ifaceClass = Class.forName(serviceInterface + "$Iface");
                Constructor<?> constructor = processorClass.getConstructor(ifaceClass);
                Object impl = entry.getValue();
                TProcessor processor = (TProcessor) constructor.newInstance(impl);

                mp.registerProcessor(serviceInterface, processor);
            }

            TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(socket);
            args.processor(mp);
            args.transportFactory(new TFramedTransport.Factory());
            args.protocolFactory(new TCompactProtocol.Factory());

            TServer server = new TThreadedSelectorServer(args);
            server.serve();

            //TODO 注册服务
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Map<String, Object> exposedServerMap = new HashMap<>();
        exposedServerMap.put(HelloWorldService.class.getName(), new HelloWorldImpl());
        new CommonServerDemo(8089, exposedServerMap).start();
    }
}

2.客户端构建一个连接池

2.1连接提供者接口

public interface ConnectionProvider {

    TTransport getConnection();

    void returnConnection(TTransport tSocket);

}

2.2连接提供者实现

我们使用的是apache 的 commons-pool实现连接池
public class ConnectionProviderImpl implements ConnectionProvider {

    private String ip;

    private int port;

    private int readTimeout;

    private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;

    private int maxIdel = GenericObjectPool.DEFAULT_MAX_IDLE;

    private int minIdel = GenericObjectPool.DEFAULT_MIN_IDLE;

    private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;

    /**
     * 取对象时 是否测试可用
     */
    private boolean testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW;

    /**
     * 还对象时 是否测试可用
     */
    private boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN;

    /**
     * 空闲的时候 是否测试可用
     */
    private boolean testWhileIdel = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE;

    private GenericObjectPool<TTransport> objectPool;

    public void init() {
        ThriftPoolableObjectFactory factory = new ThriftPoolableObjectFactory(ip, port, readTimeout);
        objectPool = new GenericObjectPool<>(factory);

        objectPool.setMaxActive(maxActive);
        objectPool.setMaxIdle(maxIdel);
        objectPool.setMinIdle(minIdel);
        objectPool.setMaxWait(maxWait);
        objectPool.setTestOnBorrow(testOnBorrow);
        objectPool.setTestOnReturn(testOnReturn);
        objectPool.setTestWhileIdle(testWhileIdel);
        //链接耗尽时应该怎么做
        objectPool.setWhenExhaustedAction(GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION);
    }

    public void destory() {
        try {
            objectPool.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public TTransport getConnection() {
        try {
            return objectPool.borrowObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void returnConnection(TTransport tSocket) {
        try {
            objectPool.returnObject(tSocket);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getReadTimeout() {
        return readTimeout;
    }

    public void setReadTimeout(int readTimeout) {
        this.readTimeout = readTimeout;
    }

    public int getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    public int getMaxIdel() {
        return maxIdel;
    }

    public void setMaxIdel(int maxIdel) {
        this.maxIdel = maxIdel;
    }

    public int getMinIdel() {
        return minIdel;
    }

    public void setMinIdel(int minIdel) {
        this.minIdel = minIdel;
    }

    public long getMaxWait() {
        return maxWait;
    }

    public void setMaxWait(long maxWait) {
        this.maxWait = maxWait;
    }

    public boolean isTestOnBorrow() {
        return testOnBorrow;
    }

    public void setTestOnBorrow(boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }

    public boolean isTestOnReturn() {
        return testOnReturn;
    }

    public void setTestOnReturn(boolean testOnReturn) {
        this.testOnReturn = testOnReturn;
    }

    public boolean isTestWhileIdel() {
        return testWhileIdel;
    }

    public void setTestWhileIdel(boolean testWhileIdel) {
        this.testWhileIdel = testWhileIdel;
    }
}

/**
 * 连接的管理
 */
public class ThriftPoolableObjectFactory implements PoolableObjectFactory<TTransport> {

    private String ip;
    private int port;
    private int readTimeOut;

    public ThriftPoolableObjectFactory(String ip, int port, int readTimeOut) {
        this.ip = ip;
        this.port = port;
        this.readTimeOut = readTimeOut;
    }

    @Override
    public TTransport makeObject() throws Exception {
        TTransport tTransport = new TSocket(ip, port, readTimeOut);
        tTransport.open();
        return tTransport;
    }

    @Override
    public void destroyObject(TTransport tTransport) throws Exception {
        if (tTransport.isOpen()) {
            tTransport.close();
        }

    }

    @Override
    public boolean validateObject(TTransport tTransport) {
        try {
            if (tTransport.isOpen()) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 激活对象
     */
    @Override
    public void activateObject(TTransport tTransport) throws Exception {

    }

    /**
     * 钝化对象
     */
    @Override
    public void passivateObject(TTransport tTransport) throws Exception {

    }
}

2.3通过ThreadLocal 实现连接的获取和返还

public class ConnectionManager {

    private static final ThreadLocal<TTransport> transportThreadLocal = new ThreadLocal<>();

    private ConnectionProvider connectionProvider;

    public TTransport getConnection() {
        TTransport connection = connectionProvider.getConnection();
        transportThreadLocal.set(connection);
        return connection;
    }

    public void returnConnection() {
        try {
            TTransport tTransport = transportThreadLocal.get();
            connectionProvider.returnConnection(tTransport);
        }finally {
            transportThreadLocal.remove();
        }
    }
    public void setConnectionProvider(ConnectionProvider connectionProvider) {
        this.connectionProvider = connectionProvider;
    }
}

3.客户端通过FactoryBean生成代理

public class CommonClientDemo<T> implements FactoryBean<T> {

    /**
     * 获取连接和返还连接
     */
    private ConnectionManager connectionManager;

    /**
     * 服务的Iface接口
     */
    private Class interfaces;

    /**
     * 服务的Client类构造器
     */
    private Constructor<?> constructor;

    /**
     * 服务类完整路径
     */
    private String serviceName;

    public CommonClientDemo(String hostName, int port, int timeOut, Class serviceClazz) {
        try {
            ConnectionProviderImpl connectionProvider = new ConnectionProviderImpl();
            connectionProvider.setIp(hostName);
            connectionProvider.setPort(port);
            connectionProvider.setReadTimeout(timeOut);
            connectionProvider.init();

            connectionManager = new ConnectionManager();
            connectionManager.setConnectionProvider(connectionProvider);
            serviceName = serviceClazz.getName();
            //获得service里面的Iface 接口
            interfaces = Class.forName(serviceName + "$Iface");
            //获得service里面的Client            Class<?> clientClass = Class.forName(serviceName + "$Client");
            constructor = clientClass.getConstructor(TProtocol.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public T getObject() {
        try {
            //创建代理
            ClassLoader classLoader = this.getClass().getClassLoader();
            return (T) newProxyInstance(classLoader, new Class[]{interfaces}, new InvocationHandler() {
                @Override
                public Object invoke(Object o, Method method, Object[] params) throws Throwable {
                    try {
                        TTransport tTransport = connectionManager.getConnection();
                        TFramedTransport tFramedTransport = new TFramedTransport(tTransport);
                        TProtocol protocol = new TCompactProtocol(tFramedTransport);

                        TMultiplexedProtocol map = new TMultiplexedProtocol(protocol, serviceName);

                        //创建client实例
                        Object target = constructor.newInstance(map);

                        return method.invoke(target, params);
                    } finally {
                        connectionManager.returnConnection();
                    }
                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Class<?> getObjectType() {
        return interfaces;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    public static void main(String[] args) throws TException {
        CommonClientDemo<HelloWorldService.Iface> commonClientDemo = new CommonClientDemo<>("localhost", 8089, 1000, HelloWorldService.class);
        HelloWorldService.Iface client = commonClientDemo.getObject();
        System.out.println(commonClientDemo.getObjectType());
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10000; i++) {
            final int index = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        String zhp = client.sayHello("zhp" + index);
                        System.out.println(zhp);
                    } catch (TException e) {
                        e.printStackTrace();
                    }

                }
            });

        }
        executorService.shutdown();
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值