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
|
cn.hippo4j.rpc.discovery.InstanceServerLoaderImpl
|
Loading…
Reference in new issue