Apache Thrift RejectedExecutionException

时间:2014-04-29 16:36:06

标签: multithreading thrift

我的应用程序由Apache Thrift连接的PHP客户端和Java后端组成,我遇到了Thrift线程池的问题。 如果我运行PHP测试,通过Thrift向后端发送请求,我得到一个异常

TSocket: timed out reading 4 bytes from localhost:34567

同时我在Java端的日志中看到以下内容:

java.util.concurrent.RejectedExecutionException: Task org.apache.thrift.server.TThreadPoolServer$WorkerProcess@17a0d6f rejected from java.util.concurrent.ThreadPoolExecutor@80080[Running, pool size = 50, active threads = 50, queued tasks = 0, completed tasks = 0]

因此,从我的角度来看,这意味着单线程同步PHP应用程序使用所有已配置的线程(50),这很奇怪。 我使用Apache Thrift 0.9.0,PHP 5.4.13和Java 1.7.0_45

Java服务器代码:

public class ThriftServer implements TransportServer {
    private static Logger logger = LoggerFactory.getLogger(ThriftServer.class);

    private final TServer server;
    private final SprootService service;
    private final int port;

    public ThriftServer(Integer thriftPort) throws IOException, ThriftException,    ConfigurationException, ConfigValidationException {
        this.service = new SprootService();
        this.port = thriftPort;
        try {
            TProcessor processor = new TSprootService.Processor<SprootService>(service);
            TServerSocket socket = new TServerSocket(port);
            TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory(true, true);
            ThreadPoolServerArgs targs = new ThreadPoolServerArgs(socket, processor, protocolFactory, 5, 50);
            this.server = new TThreadPoolServer(targs);
        } catch (TTransportException tte) {
            throw new ThriftException("Exception has occured during attempt to create Thrift server on port " + port, tte);
        }
    }

    public void start() {        
        logger.info("Thrift server is started on port " + port);
        System.out.println("Thrift server is started on port " + port);
        server.serve();
    }
}

PHP客户端代码:

class SprootClient {

    private $thriftClient = null;
    private $mappersRegistry = null;
    private $tSocket = null;

    public function __construct($host, $port) {
        $this->thriftClient = $this->initThriftClient($host, $port);
        $this->mappersRegistry = new MappersRegistry();
    }

    public function __destruct() {
        $this->tSocket->close();
    }

    private function initThriftClient($host, $port) {
        settype($port, 'integer');
        $this->tSocket = new TSocket($host, $port);
        $this->tSocket->setRecvTimeout(3000);
        try {
            $this->tSocket -> open();
            $protocol = new TBinaryProtocol($this->tSocket);
            return new TSprootServiceClient($protocol);
        } catch (Exception $e) {
            throw new SprootClientException($e->getMessage()." ".$e->getTraceAsString());
        }
    }

    private function getThriftClient() {
        return $this->thriftClient;
    }

    public function put($cacheName, $key, $domainObject) {
        if ($domainObject == null || $key == null) {
            throw new SprootClientException("Both key and value cannot be null or empty");
        }
        try {
            $mapper = $this->mappersRegistry->getDomainMapper($cacheName);
            $dataObject = $mapper->toTDataObject($domainObject);
            $this->getThriftClient()->put($cacheName, $key, $dataObject);
        } catch (Exception $e) {
            throw new SprootClientException($e->getMessage()." ".$e->getTraceAsString());
    }
}

0 个答案:

没有答案