mirror of https://github.com/longtai-cn/hippo4j
fix : The rpc module is tuned to start the server asynchronously and … (#973)
* fix : The rpc module is tuned to start the server asynchronously and use the InetSocketAddress proxy host and port * fix : Modify the logic waiting for the server to start in the test * fix : The rpc module dependency change to commonpull/975/head
parent
cd9a9de5bf
commit
a54899e793
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.rpc.support;
|
||||
|
||||
import cn.hippo4j.rpc.client.Client;
|
||||
import cn.hippo4j.rpc.discovery.DiscoveryAdapter;
|
||||
import cn.hippo4j.rpc.exception.ConnectionException;
|
||||
import cn.hippo4j.rpc.handler.NettyClientPoolHandler;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* A FactoryBean that builds interfaces to invoke proxy objects
|
||||
* is responsible for managing the entire life cycle of the proxy objects<br>
|
||||
*
|
||||
* @deprecated With {@link cn.hippo4j.config.service.ThreadPoolAdapterService} structure, FactoryBean is not the best choice
|
||||
*/
|
||||
@Deprecated
|
||||
public class ClientFactoryBean implements FactoryBean<Object>, InitializingBean, ApplicationContextAware, DisposableBean {
|
||||
|
||||
/**
|
||||
* Application name or address string. If it is an address string, it must be in ip:port format
|
||||
*/
|
||||
private String applicationName;
|
||||
|
||||
/**
|
||||
* The adapter name in the container needs to be used with applicationName
|
||||
* to get the real server address. If it is null or the address information
|
||||
* cannot be found, applicationName is treated as an address string
|
||||
*/
|
||||
private String discoveryAdapterName;
|
||||
|
||||
private DiscoveryAdapter discoveryAdapter;
|
||||
|
||||
/**
|
||||
* the channel handler
|
||||
*/
|
||||
private ChannelHandler[] handlers;
|
||||
|
||||
/**
|
||||
* Type of the proxy interface
|
||||
*/
|
||||
private Class<?> cls;
|
||||
|
||||
/**
|
||||
* Container Context
|
||||
*/
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* InetSocketAddress
|
||||
*/
|
||||
InetSocketAddress address;
|
||||
|
||||
public ClientFactoryBean(String applicationName, String discoveryAdapterName, Class<?> cls) {
|
||||
this.applicationName = applicationName;
|
||||
this.discoveryAdapterName = discoveryAdapterName;
|
||||
this.cls = cls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
this.address = discoveryAdapter.getSocketAddress(applicationName);
|
||||
if (this.address == null) {
|
||||
String[] addressStr = applicationName.split(":");
|
||||
if (addressStr.length < 2) {
|
||||
throw new ConnectionException("Failed to connect to the server because the IP address is invalid. Procedure");
|
||||
}
|
||||
this.address = InetSocketAddress.createUnresolved(addressStr[0], Integer.parseInt(addressStr[1]));
|
||||
}
|
||||
NettyClientPoolHandler handler = new NettyClientPoolHandler(handlers);
|
||||
Client client = NettyClientSupport.getClient(this.address, handler);
|
||||
return NettyProxyCenter.createProxy(client, cls, this.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.discoveryAdapter = (DiscoveryAdapter) applicationContext.getBean(discoveryAdapterName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
if (this.address == null) {
|
||||
return;
|
||||
}
|
||||
NettyClientSupport.closeClient(this.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public ClientFactoryBean applicationName(String applicationName) {
|
||||
this.applicationName = applicationName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientFactoryBean discoveryAdapterName(String discoveryAdapterName) {
|
||||
this.discoveryAdapterName = discoveryAdapterName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientFactoryBean cls(Class<?> cls) {
|
||||
this.cls = cls;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientFactoryBean handlers(ChannelHandler[] handlers) {
|
||||
this.handlers = handlers;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.rpc.support;
|
||||
|
||||
import cn.hippo4j.common.web.exception.IllegalException;
|
||||
import cn.hippo4j.rpc.client.Client;
|
||||
import cn.hippo4j.rpc.client.ClientConnection;
|
||||
import cn.hippo4j.rpc.client.NettyClientConnection;
|
||||
import cn.hippo4j.rpc.client.RPCClient;
|
||||
import cn.hippo4j.rpc.handler.HandlerManager;
|
||||
import cn.hippo4j.rpc.handler.NettyClientPoolHandler;
|
||||
import cn.hippo4j.rpc.handler.NettyClientTakeHandler;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Different from the management of the server side, in order not to waste resources, we pool the
|
||||
* connections of different addresses and turn the client into a one-time resource. If there is no
|
||||
* support from the container, the client is a resource that can be recovered after use. This is
|
||||
* similar to {@link WeakReference}, but the client needs the user to set the life cycle.<br>
|
||||
* <p>
|
||||
* Typically, the client is just a front for the direct connection between the client and the server,
|
||||
* and for any call to succeed, only the {@link ClientConnection} connection is required. In the
|
||||
* presence of a container, it is necessary to keep the client active for a long time, when the
|
||||
* client should be a specific resource in the container, following the resource lifecycle specified
|
||||
* by the container
|
||||
*
|
||||
* @see cn.hippo4j.rpc.client.RPCClient
|
||||
* @see cn.hippo4j.rpc.client.NettyClientConnection
|
||||
* @see NettyServerSupport
|
||||
* @see ClientFactoryBean
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public final class NettyClientSupport {
|
||||
|
||||
/**
|
||||
* the cache for client
|
||||
*/
|
||||
private static final Map<InetSocketAddress, Client> clientMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Obtain the client connected to the server through the server address. If the client does not exist, create one
|
||||
*
|
||||
* @param address the address
|
||||
* @param handlerManager the handlerManager
|
||||
* @return Client
|
||||
*/
|
||||
public static Client getClient(InetSocketAddress address, HandlerManager<ChannelHandler> handlerManager) {
|
||||
return clientMap.computeIfAbsent(address, a -> {
|
||||
NettyClientPoolHandler handler = (handlerManager instanceof NettyClientPoolHandler)
|
||||
? (NettyClientPoolHandler) handlerManager
|
||||
: new NettyClientPoolHandler();
|
||||
if (handler.isEmpty()) {
|
||||
handler.addFirst(new NettyClientTakeHandler());
|
||||
}
|
||||
NettyClientConnection connection = new NettyClientConnection(address, handler);
|
||||
return new RPCClient(connection);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the client connected to the server through the server address. If the client does not exist, create one by default
|
||||
*
|
||||
* @param address the address
|
||||
* @return Client
|
||||
*/
|
||||
public static Client getClient(InetSocketAddress address) {
|
||||
return getClient(address, new NettyClientPoolHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a client connected to a server address. The client may have been closed
|
||||
*
|
||||
* @param address the address
|
||||
*/
|
||||
public static void closeClient(InetSocketAddress address) {
|
||||
Client client = clientMap.remove(address);
|
||||
try {
|
||||
if (client != null) {
|
||||
client.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +1,18 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
cn.hippo4j.rpc.discovery.InstanceServerLoaderImpl
|
Loading…
Reference in new issue