提交 f83e70b5 编写于 作者: Y YunaiV

dubbo rpc redis 等等

上级 408eeb2a
...@@ -52,14 +52,11 @@ limitations under the License. ...@@ -52,14 +52,11 @@ limitations under the License.
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>dubbo-cluster</artifactId> <artifactId>dubbo-cluster</artifactId>
</dependency> </dependency>
<!--<dependency>--> <dependency>
<!--<groupId>com.alibaba</groupId>--> <groupId>com.alibaba</groupId>
<!--<artifactId>dubbo-rpc-http</artifactId>--> <artifactId>dubbo-rpc-http</artifactId>
<!--</dependency>--> </dependency>
<!--<dependency>-->
<!--<groupId>com.alibaba</groupId>-->
<!--<artifactId>dubbo-remoting-http</artifactId>-->
<!--</dependency>-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
......
package com.alibaba.dubbo.demo.provider;
import com.alibaba.dubbo.demo.HttpDemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HttpConsumer {
public static void main(String[] args) {
System.setProperty("java.net.preferIPv4Stack", "true");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
context.start();
HttpDemoService demoService = (HttpDemoService) context.getBean("demoService"); // get remote service proxy
while (true) {
try {
Thread.sleep(1000);
String hello = demoService.hello("world"); // call remote method
System.out.println(hello); // get result
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
}
...@@ -21,21 +21,17 @@ limitations under the License. ...@@ -21,21 +21,17 @@ limitations under the License.
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship --> <!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
<dubbo:application name="demo-provider"/> don't set it same as provider -->
<dubbo:application name="demo-consumer" />
<dubbo:provider delay="-1" retries="0" />
<!-- use multicast registry center to discover service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!--<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>
<!-- generate proxy for the remote service, then demoService can be used in the same way as the
<!-- declare the service interface to be exported --> local regular interface -->
<dubbo:service interface="com.alibaba.dubbo.demo.HttpDemoService" ref="demoService"> <dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.demo.HttpDemoService" >
</dubbo:service> </dubbo:reference>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="http" port="8080" server="tomcat" />
<!--<dubbo:protocol id="pb" name="dubbo" port="20881"/>-->
</beans> </beans>
\ No newline at end of file
...@@ -65,16 +65,27 @@ public class RpcContext { ...@@ -65,16 +65,27 @@ public class RpcContext {
private final Map<String, String> attachments = new HashMap<String, String>(); private final Map<String, String> attachments = new HashMap<String, String>();
private final Map<String, Object> values = new HashMap<String, Object>(); private final Map<String, Object> values = new HashMap<String, Object>();
/**
* 异步调用 Future
*/
private Future<?> future; private Future<?> future;
private List<URL> urls; private List<URL> urls;
/**
* URL 对象
*/
private URL url; private URL url;
/**
* 方法名
*/
private String methodName; private String methodName;
/**
* 参数类型数组
*/
private Class<?>[] parameterTypes; private Class<?>[] parameterTypes;
/**
* 参数值数组
*/
private Object[] arguments; private Object[] arguments;
/** /**
* 服务消费者地址 * 服务消费者地址
......
...@@ -75,6 +75,7 @@ public abstract class AbstractProtocol implements Protocol { ...@@ -75,6 +75,7 @@ public abstract class AbstractProtocol implements Protocol {
return ProtocolUtils.serviceKey(port, serviceName, serviceVersion, serviceGroup); return ProtocolUtils.serviceKey(port, serviceName, serviceVersion, serviceGroup);
} }
@Override
public void destroy() { public void destroy() {
for (Invoker<?> invoker : invokers) { for (Invoker<?> invoker : invokers) {
if (invoker != null) { if (invoker != null) {
......
...@@ -32,11 +32,18 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -32,11 +32,18 @@ import java.util.concurrent.CopyOnWriteArrayList;
/** /**
* AbstractProxyProtocol * AbstractProxyProtocol
*
* Proxy 协议抽象类
*/ */
public abstract class AbstractProxyProtocol extends AbstractProtocol { public abstract class AbstractProxyProtocol extends AbstractProtocol {
/**
* 需要抛出的异常类集合,详见 {@link #refer(Class, URL)} 方法。
*/
private final List<Class<?>> rpcExceptions = new CopyOnWriteArrayList<Class<?>>(); private final List<Class<?>> rpcExceptions = new CopyOnWriteArrayList<Class<?>>();
/**
* ProxyFactory 对象
*/
private ProxyFactory proxyFactory; private ProxyFactory proxyFactory;
public AbstractProxyProtocol() { public AbstractProxyProtocol() {
...@@ -60,18 +67,27 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol { ...@@ -60,18 +67,27 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol {
this.proxyFactory = proxyFactory; this.proxyFactory = proxyFactory;
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException { public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException {
// 获得服务键
final String uri = serviceKey(invoker.getUrl()); final String uri = serviceKey(invoker.getUrl());
// 获得 Exporter 对象。若已经暴露,直接返回。
Exporter<T> exporter = (Exporter<T>) exporterMap.get(uri); Exporter<T> exporter = (Exporter<T>) exporterMap.get(uri);
if (exporter != null) { if (exporter != null) {
return exporter; return exporter;
} }
// 执行暴露服务
final Runnable runnable = doExport(proxyFactory.getProxy(invoker), invoker.getInterface(), invoker.getUrl()); final Runnable runnable = doExport(proxyFactory.getProxy(invoker), invoker.getInterface(), invoker.getUrl());
// 创建 Exporter 对象
exporter = new AbstractExporter<T>(invoker) { exporter = new AbstractExporter<T>(invoker) {
@Override
public void unexport() { public void unexport() {
// 取消暴露
super.unexport(); super.unexport();
exporterMap.remove(uri); exporterMap.remove(uri);
// 执行取消暴露的回调
if (runnable != null) { if (runnable != null) {
try { try {
runnable.run(); runnable.run();
...@@ -80,18 +96,26 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol { ...@@ -80,18 +96,26 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol {
} }
} }
} }
}; };
// 添加到 Exporter 集合
exporterMap.put(uri, exporter); exporterMap.put(uri, exporter);
return exporter; return exporter;
} }
@Override
public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException { public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException {
final Invoker<T> tagert = proxyFactory.getInvoker(doRefer(type, url), type, url); // 执行引用服务
final Invoker<T> target = proxyFactory.getInvoker(doRefer(type, url), type, url);
// 创建 Invoker 对象
Invoker<T> invoker = new AbstractInvoker<T>(type, url) { Invoker<T> invoker = new AbstractInvoker<T>(type, url) {
@Override @Override
protected Result doInvoke(Invocation invocation) throws Throwable { protected Result doInvoke(Invocation invocation) throws Throwable {
try { try {
Result result = tagert.invoke(invocation); // 调用
Result result = target.invoke(invocation);
// 若返回结果带有异常,并且需要抛出,则抛出异常。
Throwable e = result.getException(); Throwable e = result.getException();
if (e != null) { if (e != null) {
for (Class<?> rpcException : rpcExceptions) { for (Class<?> rpcException : rpcExceptions) {
...@@ -102,15 +126,19 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol { ...@@ -102,15 +126,19 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol {
} }
return result; return result;
} catch (RpcException e) { } catch (RpcException e) {
// 若是未知异常,获得异常对应的错误码
if (e.getCode() == RpcException.UNKNOWN_EXCEPTION) { if (e.getCode() == RpcException.UNKNOWN_EXCEPTION) {
e.setCode(getErrorCode(e.getCause())); e.setCode(getErrorCode(e.getCause()));
} }
throw e; throw e;
} catch (Throwable e) { } catch (Throwable e) {
// 抛出 RpcException 异常
throw getRpcException(type, url, invocation, e); throw getRpcException(type, url, invocation, e);
} }
} }
}; };
// 添加到 Invoker 集合。
invokers.add(invoker); invokers.add(invoker);
return invoker; return invoker;
} }
...@@ -130,12 +158,37 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol { ...@@ -130,12 +158,37 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol {
return NetUtils.getIpByHost(bindIp) + ":" + url.getParameter(Constants.BIND_PORT_KEY, url.getPort()); return NetUtils.getIpByHost(bindIp) + ":" + url.getParameter(Constants.BIND_PORT_KEY, url.getPort());
} }
/**
* 获得异常对应的错误码
*
* @param e 异常
* @return 错误码
*/
protected int getErrorCode(Throwable e) { protected int getErrorCode(Throwable e) {
return RpcException.UNKNOWN_EXCEPTION; return RpcException.UNKNOWN_EXCEPTION;
} }
/**
* 执行暴露,并返回取消暴露的回调 Runnable
*
* @param impl 服务 Proxy 对象
* @param type 服务接口
* @param url URL
* @param <T> 服务接口
* @return 消暴露的回调 Runnable
* @throws RpcException 当发生异常
*/
protected abstract <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException; protected abstract <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException;
/**
* 执行引用,并返回调用远程服务的 Service 对象
*
* @param type 服务接口
* @param url URL
* @param <T> 服务接口
* @return 调用远程服务的 Service 对象
* @throws RpcException 当发生异常
*/
protected abstract <T> T doRefer(Class<T> type, URL url) throws RpcException; protected abstract <T> T doRefer(Class<T> type, URL url) throws RpcException;
} }
...@@ -54,7 +54,7 @@ final public class MockInvoker<T> implements Invoker<T> { ...@@ -54,7 +54,7 @@ final public class MockInvoker<T> implements Invoker<T> {
} }
public static Object parseMockValue(String mock, Type[] returnTypes) throws Exception { public static Object parseMockValue(String mock, Type[] returnTypes) throws Exception {
Object value = null; Object value;
if ("empty".equals(mock)) { if ("empty".equals(mock)) {
value = ReflectUtils.getEmptyObject(returnTypes != null && returnTypes.length > 0 ? (Class<?>) returnTypes[0] : null); value = ReflectUtils.getEmptyObject(returnTypes != null && returnTypes.length > 0 ? (Class<?>) returnTypes[0] : null);
} else if ("null".equals(mock)) { } else if ("null".equals(mock)) {
......
...@@ -42,13 +42,26 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -42,13 +42,26 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* http rpc support. * http rpc support.
*
* Hessian 协议实现类
*/ */
public class HessianProtocol extends AbstractProxyProtocol { public class HessianProtocol extends AbstractProxyProtocol {
/**
* Http 服务器集合
*
* key:ip:port
*/
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>(); private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
/**
* Spring HttpInvokerServiceExporter 集合
*
* key:path 服务名
*/
private final Map<String, HessianSkeleton> skeletonMap = new ConcurrentHashMap<String, HessianSkeleton>(); private final Map<String, HessianSkeleton> skeletonMap = new ConcurrentHashMap<String, HessianSkeleton>();
/**
* HttpBinder$Adaptive 对象
*/
private HttpBinder httpBinder; private HttpBinder httpBinder;
public HessianProtocol() { public HessianProtocol() {
...@@ -63,16 +76,21 @@ public class HessianProtocol extends AbstractProxyProtocol { ...@@ -63,16 +76,21 @@ public class HessianProtocol extends AbstractProxyProtocol {
return 80; return 80;
} }
@Override
protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException { protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
// 获得服务器地址
String addr = getAddr(url); String addr = getAddr(url);
// 获得 HttpServer 对象。若不存在,进行创建。
HttpServer server = serverMap.get(addr); HttpServer server = serverMap.get(addr);
if (server == null) { if (server == null) {
server = httpBinder.bind(url, new HessianHandler()); server = httpBinder.bind(url, new HessianHandler()); // HessianHandler
serverMap.put(addr, server); serverMap.put(addr, server);
} }
// 添加到 skeletonMap 中
final String path = url.getAbsolutePath(); final String path = url.getAbsolutePath();
HessianSkeleton skeleton = new HessianSkeleton(impl, type); HessianSkeleton skeleton = new HessianSkeleton(impl, type);
skeletonMap.put(path, skeleton); skeletonMap.put(path, skeleton);
// 返回取消暴露的回调 Runnable
return new Runnable() { return new Runnable() {
public void run() { public void run() {
skeletonMap.remove(path); skeletonMap.remove(path);
...@@ -80,21 +98,27 @@ public class HessianProtocol extends AbstractProxyProtocol { ...@@ -80,21 +98,27 @@ public class HessianProtocol extends AbstractProxyProtocol {
}; };
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T doRefer(Class<T> serviceType, URL url) throws RpcException { protected <T> T doRefer(Class<T> serviceType, URL url) throws RpcException {
// 创建 HessianProxyFactory 对象
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory(); HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
// 创建连接器工厂为 HttpClientConnectionFactory 对象,即 Apache HttpClient
String client = url.getParameter(Constants.CLIENT_KEY, Constants.DEFAULT_HTTP_CLIENT); String client = url.getParameter(Constants.CLIENT_KEY, Constants.DEFAULT_HTTP_CLIENT);
if ("httpclient".equals(client)) { if ("httpclient".equals(client)) {
hessianProxyFactory.setConnectionFactory(new HttpClientConnectionFactory()); hessianProxyFactory.setConnectionFactory(new HttpClientConnectionFactory());
} else if (client != null && client.length() > 0 && !Constants.DEFAULT_HTTP_CLIENT.equals(client)) { } else if (client != null && client.length() > 0 && !Constants.DEFAULT_HTTP_CLIENT.equals(client)) {
throw new IllegalStateException("Unsupported http protocol client=\"" + client + "\"!"); throw new IllegalStateException("Unsupported http protocol client=\"" + client + "\"!");
} }
// 设置超时时间
int timeout = url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT); int timeout = url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
hessianProxyFactory.setConnectTimeout(timeout); hessianProxyFactory.setConnectTimeout(timeout);
hessianProxyFactory.setReadTimeout(timeout); hessianProxyFactory.setReadTimeout(timeout);
// 创建 Service Proxy 对象
return (T) hessianProxyFactory.create(serviceType, url.setProtocol("http").toJavaURL(), Thread.currentThread().getContextClassLoader()); return (T) hessianProxyFactory.create(serviceType, url.setProtocol("http").toJavaURL(), Thread.currentThread().getContextClassLoader());
} }
@Override
protected int getErrorCode(Throwable e) { protected int getErrorCode(Throwable e) {
if (e instanceof HessianConnectionException) { if (e instanceof HessianConnectionException) {
if (e.getCause() != null) { if (e.getCause() != null) {
...@@ -110,8 +134,11 @@ public class HessianProtocol extends AbstractProxyProtocol { ...@@ -110,8 +134,11 @@ public class HessianProtocol extends AbstractProxyProtocol {
return super.getErrorCode(e); return super.getErrorCode(e);
} }
@Override
public void destroy() { public void destroy() {
// 销毁
super.destroy(); super.destroy();
// 销毁 HttpServer
for (String key : new ArrayList<String>(serverMap.keySet())) { for (String key : new ArrayList<String>(serverMap.keySet())) {
HttpServer server = serverMap.remove(key); HttpServer server = serverMap.remove(key);
if (server != null) { if (server != null) {
...@@ -129,12 +156,16 @@ public class HessianProtocol extends AbstractProxyProtocol { ...@@ -129,12 +156,16 @@ public class HessianProtocol extends AbstractProxyProtocol {
private class HessianHandler implements HttpHandler { private class HessianHandler implements HttpHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) public void handle(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException { throws IOException, ServletException {
String uri = request.getRequestURI(); String uri = request.getRequestURI();
// 获得 HessianSkeleton 对象
HessianSkeleton skeleton = skeletonMap.get(uri); HessianSkeleton skeleton = skeletonMap.get(uri);
// 必须是 POST 请求
if (!request.getMethod().equalsIgnoreCase("POST")) { if (!request.getMethod().equalsIgnoreCase("POST")) {
response.setStatus(500); response.setStatus(500);
// 执行调用
} else { } else {
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort()); RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
try { try {
......
...@@ -34,6 +34,9 @@ import java.net.URL; ...@@ -34,6 +34,9 @@ import java.net.URL;
*/ */
public class HttpClientConnection implements HessianConnection { public class HttpClientConnection implements HessianConnection {
/**
* Apache HttpClient
*/
private final HttpClient httpClient; private final HttpClient httpClient;
private final ByteArrayOutputStream output; private final ByteArrayOutputStream output;
...@@ -48,35 +51,43 @@ public class HttpClientConnection implements HessianConnection { ...@@ -48,35 +51,43 @@ public class HttpClientConnection implements HessianConnection {
this.request = new HttpPost(url.toString()); this.request = new HttpPost(url.toString());
} }
@Override
public void addHeader(String key, String value) { public void addHeader(String key, String value) {
request.addHeader(new BasicHeader(key, value)); request.addHeader(new BasicHeader(key, value));
} }
@Override
public OutputStream getOutputStream() throws IOException { public OutputStream getOutputStream() throws IOException {
return output; return output;
} }
@Override
public void sendRequest() throws IOException { public void sendRequest() throws IOException {
request.setEntity(new ByteArrayEntity(output.toByteArray())); request.setEntity(new ByteArrayEntity(output.toByteArray()));
this.response = httpClient.execute(request); this.response = httpClient.execute(request);
} }
@Override
public int getStatusCode() { public int getStatusCode() {
return response == null || response.getStatusLine() == null ? 0 : response.getStatusLine().getStatusCode(); return response == null || response.getStatusLine() == null ? 0 : response.getStatusLine().getStatusCode();
} }
@Override
public String getStatusMessage() { public String getStatusMessage() {
return response == null || response.getStatusLine() == null ? null : response.getStatusLine().getReasonPhrase(); return response == null || response.getStatusLine() == null ? null : response.getStatusLine().getReasonPhrase();
} }
@Override
public String getContentEncoding() { public String getContentEncoding() {
return (response == null || response.getEntity() == null || response.getEntity().getContentEncoding() == null) ? null : response.getEntity().getContentEncoding().getValue(); return (response == null || response.getEntity() == null || response.getEntity().getContentEncoding() == null) ? null : response.getEntity().getContentEncoding().getValue();
} }
@Override
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return response == null || response.getEntity() == null ? null : response.getEntity().getContent(); return response == null || response.getEntity() == null ? null : response.getEntity().getContent();
} }
@Override
public void close() throws IOException { public void close() throws IOException {
HttpPost request = this.request; HttpPost request = this.request;
if (request != null) { if (request != null) {
...@@ -84,6 +95,7 @@ public class HttpClientConnection implements HessianConnection { ...@@ -84,6 +95,7 @@ public class HttpClientConnection implements HessianConnection {
} }
} }
@Override
public void destroy() throws IOException { public void destroy() throws IOException {
} }
......
...@@ -23,7 +23,6 @@ import org.apache.http.client.HttpClient; ...@@ -23,7 +23,6 @@ import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpConnectionParams;
import java.io.IOException;
import java.net.URL; import java.net.URL;
/** /**
...@@ -31,15 +30,20 @@ import java.net.URL; ...@@ -31,15 +30,20 @@ import java.net.URL;
*/ */
public class HttpClientConnectionFactory implements HessianConnectionFactory { public class HttpClientConnectionFactory implements HessianConnectionFactory {
/**
* Apache HttpClient
*/
private final HttpClient httpClient = new DefaultHttpClient(); private final HttpClient httpClient = new DefaultHttpClient();
@Override
public void setHessianProxyFactory(HessianProxyFactory factory) { public void setHessianProxyFactory(HessianProxyFactory factory) {
HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), (int) factory.getConnectTimeout()); HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), (int) factory.getConnectTimeout());
HttpConnectionParams.setSoTimeout(httpClient.getParams(), (int) factory.getReadTimeout()); HttpConnectionParams.setSoTimeout(httpClient.getParams(), (int) factory.getReadTimeout());
} }
public HessianConnection open(URL url) throws IOException { @Override
return new HttpClientConnection(httpClient, url); public HessianConnection open(URL url) {
return new HttpClientConnection(httpClient, url); // HttpClientConnection
} }
} }
\ No newline at end of file
...@@ -42,15 +42,30 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -42,15 +42,30 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* HttpProtocol * HttpProtocol
*
* HTTP 协议实现类
*/ */
public class HttpProtocol extends AbstractProxyProtocol { public class HttpProtocol extends AbstractProxyProtocol {
/**
* 默认服务器端口
*/
public static final int DEFAULT_PORT = 80; public static final int DEFAULT_PORT = 80;
/**
* Http 服务器集合
*
* key:ip:port
*/
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>(); private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
/**
* Spring HttpInvokerServiceExporter 集合
*
* key:path 服务名
*/
private final Map<String, HttpInvokerServiceExporter> skeletonMap = new ConcurrentHashMap<String, HttpInvokerServiceExporter>(); private final Map<String, HttpInvokerServiceExporter> skeletonMap = new ConcurrentHashMap<String, HttpInvokerServiceExporter>();
/**
* HttpBinder$Adaptive 对象
*/
private HttpBinder httpBinder; private HttpBinder httpBinder;
public HttpProtocol() { public HttpProtocol() {
...@@ -65,13 +80,17 @@ public class HttpProtocol extends AbstractProxyProtocol { ...@@ -65,13 +80,17 @@ public class HttpProtocol extends AbstractProxyProtocol {
return DEFAULT_PORT; return DEFAULT_PORT;
} }
@Override
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException { protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
// 获得服务器地址
String addr = getAddr(url); String addr = getAddr(url);
// 获得 HttpServer 对象。若不存在,进行创建。
HttpServer server = serverMap.get(addr); HttpServer server = serverMap.get(addr);
if (server == null) { if (server == null) {
server = httpBinder.bind(url, new InternalHandler()); server = httpBinder.bind(url, new InternalHandler()); // InternalHandler
serverMap.put(addr, server); serverMap.put(addr, server);
} }
// 创建 HttpInvokerServiceExporter 对象
final HttpInvokerServiceExporter httpServiceExporter = new HttpInvokerServiceExporter(); final HttpInvokerServiceExporter httpServiceExporter = new HttpInvokerServiceExporter();
httpServiceExporter.setServiceInterface(type); httpServiceExporter.setServiceInterface(type);
httpServiceExporter.setService(impl); httpServiceExporter.setService(impl);
...@@ -80,8 +99,10 @@ public class HttpProtocol extends AbstractProxyProtocol { ...@@ -80,8 +99,10 @@ public class HttpProtocol extends AbstractProxyProtocol {
} catch (Exception e) { } catch (Exception e) {
throw new RpcException(e.getMessage(), e); throw new RpcException(e.getMessage(), e);
} }
// 添加到 skeletonMap 中
final String path = url.getAbsolutePath(); final String path = url.getAbsolutePath();
skeletonMap.put(path, httpServiceExporter); skeletonMap.put(path, httpServiceExporter);
// 返回取消暴露的回调 Runnable
return new Runnable() { return new Runnable() {
public void run() { public void run() {
skeletonMap.remove(path); skeletonMap.remove(path);
...@@ -89,11 +110,14 @@ public class HttpProtocol extends AbstractProxyProtocol { ...@@ -89,11 +110,14 @@ public class HttpProtocol extends AbstractProxyProtocol {
}; };
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException { protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
// 创建 HttpInvokerProxyFactoryBean 对象
final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new HttpInvokerProxyFactoryBean(); final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new HttpInvokerProxyFactoryBean();
httpProxyFactoryBean.setServiceUrl(url.toIdentityString()); httpProxyFactoryBean.setServiceUrl(url.toIdentityString());
httpProxyFactoryBean.setServiceInterface(serviceType); httpProxyFactoryBean.setServiceInterface(serviceType);
// 创建执行器 SimpleHttpInvokerRequestExecutor 对象
String client = url.getParameter(Constants.CLIENT_KEY); String client = url.getParameter(Constants.CLIENT_KEY);
if (client == null || client.length() == 0 || "simple".equals(client)) { if (client == null || client.length() == 0 || "simple".equals(client)) {
SimpleHttpInvokerRequestExecutor httpInvokerRequestExecutor = new SimpleHttpInvokerRequestExecutor() { SimpleHttpInvokerRequestExecutor httpInvokerRequestExecutor = new SimpleHttpInvokerRequestExecutor() {
...@@ -105,6 +129,7 @@ public class HttpProtocol extends AbstractProxyProtocol { ...@@ -105,6 +129,7 @@ public class HttpProtocol extends AbstractProxyProtocol {
} }
}; };
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor); httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
// 创建执行器 HttpComponentsHttpInvokerRequestExecutor 对象
} else if ("commons".equals(client)) { } else if ("commons".equals(client)) {
HttpComponentsHttpInvokerRequestExecutor httpInvokerRequestExecutor = new HttpComponentsHttpInvokerRequestExecutor(); HttpComponentsHttpInvokerRequestExecutor httpInvokerRequestExecutor = new HttpComponentsHttpInvokerRequestExecutor();
httpInvokerRequestExecutor.setReadTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT)); httpInvokerRequestExecutor.setReadTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT));
...@@ -113,9 +138,12 @@ public class HttpProtocol extends AbstractProxyProtocol { ...@@ -113,9 +138,12 @@ public class HttpProtocol extends AbstractProxyProtocol {
throw new IllegalStateException("Unsupported http protocol client " + client + ", only supported: simple, commons"); throw new IllegalStateException("Unsupported http protocol client " + client + ", only supported: simple, commons");
} }
httpProxyFactoryBean.afterPropertiesSet(); httpProxyFactoryBean.afterPropertiesSet();
// 返回 HttpInvokerProxyFactoryBean 对象
return (T) httpProxyFactoryBean.getObject(); return (T) httpProxyFactoryBean.getObject();
} }
@Override
@SuppressWarnings("Duplicates")
protected int getErrorCode(Throwable e) { protected int getErrorCode(Throwable e) {
if (e instanceof RemoteAccessException) { if (e instanceof RemoteAccessException) {
e = e.getCause(); e = e.getCause();
...@@ -135,12 +163,15 @@ public class HttpProtocol extends AbstractProxyProtocol { ...@@ -135,12 +163,15 @@ public class HttpProtocol extends AbstractProxyProtocol {
private class InternalHandler implements HttpHandler { private class InternalHandler implements HttpHandler {
public void handle(HttpServletRequest request, HttpServletResponse response) @Override
throws IOException, ServletException { public void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException {
String uri = request.getRequestURI(); String uri = request.getRequestURI();
// 获得 HttpInvokerServiceExporter 对象
HttpInvokerServiceExporter skeleton = skeletonMap.get(uri); HttpInvokerServiceExporter skeleton = skeletonMap.get(uri);
// 必须是 POST 请求
if (!request.getMethod().equalsIgnoreCase("POST")) { if (!request.getMethod().equalsIgnoreCase("POST")) {
response.setStatus(500); response.setStatus(500);
// 执行调用
} else { } else {
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort()); RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
try { try {
......
...@@ -49,12 +49,15 @@ public class MemcachedProtocol extends AbstractProtocol { ...@@ -49,12 +49,15 @@ public class MemcachedProtocol extends AbstractProtocol {
return DEFAULT_PORT; return DEFAULT_PORT;
} }
@Override
public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException { public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException {
throw new UnsupportedOperationException("Unsupported export memcached service. url: " + invoker.getUrl()); throw new UnsupportedOperationException("Unsupported export memcached service. url: " + invoker.getUrl());
} }
@Override
public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException { public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException {
try { try {
// 创建 MemcachedClient 对象
String address = url.getAddress(); String address = url.getAddress();
String backup = url.getParameter(Constants.BACKUP_KEY); String backup = url.getParameter(Constants.BACKUP_KEY);
if (backup != null && backup.length() > 0) { if (backup != null && backup.length() > 0) {
...@@ -62,30 +65,38 @@ public class MemcachedProtocol extends AbstractProtocol { ...@@ -62,30 +65,38 @@ public class MemcachedProtocol extends AbstractProtocol {
} }
MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(address)); MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(address));
final MemcachedClient memcachedClient = builder.build(); final MemcachedClient memcachedClient = builder.build();
// 处理方法名的映射
final int expiry = url.getParameter("expiry", 0); final int expiry = url.getParameter("expiry", 0);
final String get = url.getParameter("get", "get"); final String get = url.getParameter("get", "get");
final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set"); final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set");
final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete"); final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete");
return new AbstractInvoker<T>(type, url) { return new AbstractInvoker<T>(type, url) {
@Override
protected Result doInvoke(Invocation invocation) throws Throwable { protected Result doInvoke(Invocation invocation) throws Throwable {
try { try {
// Memcached get 指令
if (get.equals(invocation.getMethodName())) { if (get.equals(invocation.getMethodName())) {
if (invocation.getArguments().length != 1) { if (invocation.getArguments().length != 1) {
throw new IllegalArgumentException("The memcached get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); throw new IllegalArgumentException("The memcached get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
} }
return new RpcResult(memcachedClient.get(String.valueOf(invocation.getArguments()[0]))); return new RpcResult(memcachedClient.get(String.valueOf(invocation.getArguments()[0])));
// Memcached set 指令
} else if (set.equals(invocation.getMethodName())) { } else if (set.equals(invocation.getMethodName())) {
if (invocation.getArguments().length != 2) { if (invocation.getArguments().length != 2) {
throw new IllegalArgumentException("The memcached set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); throw new IllegalArgumentException("The memcached set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
} }
memcachedClient.set(String.valueOf(invocation.getArguments()[0]), expiry, invocation.getArguments()[1]); memcachedClient.set(String.valueOf(invocation.getArguments()[0]), expiry, invocation.getArguments()[1]);
return new RpcResult(); return new RpcResult();
// Memcached delele 指令
} else if (delete.equals(invocation.getMethodName())) { } else if (delete.equals(invocation.getMethodName())) {
if (invocation.getArguments().length != 1) { if (invocation.getArguments().length != 1) {
throw new IllegalArgumentException("The memcached delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); throw new IllegalArgumentException("The memcached delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
} }
memcachedClient.delete(String.valueOf(invocation.getArguments()[0])); memcachedClient.delete(String.valueOf(invocation.getArguments()[0]));
return new RpcResult(); return new RpcResult();
// 不支持的指令,抛出异常
} else { } else {
throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in memcached service."); throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in memcached service.");
} }
...@@ -100,14 +111,18 @@ public class MemcachedProtocol extends AbstractProtocol { ...@@ -100,14 +111,18 @@ public class MemcachedProtocol extends AbstractProtocol {
} }
} }
@Override
public void destroy() { public void destroy() {
// 标记销毁
super.destroy(); super.destroy();
// 关闭 MemcachedClient
try { try {
memcachedClient.shutdown(); memcachedClient.shutdown();
} catch (Throwable e) { } catch (Throwable e) {
logger.warn(e.getMessage(), e); logger.warn(e.getMessage(), e);
} }
} }
}; };
} catch (Throwable t) { } catch (Throwable t) {
throw new RpcException("Failed to refer memcached service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t); throw new RpcException("Failed to refer memcached service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t);
......
...@@ -56,6 +56,7 @@ public class RedisProtocol extends AbstractProtocol { ...@@ -56,6 +56,7 @@ public class RedisProtocol extends AbstractProtocol {
return DEFAULT_PORT; return DEFAULT_PORT;
} }
@Override
public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException { public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException {
throw new UnsupportedOperationException("Unsupported export redis service. url: " + invoker.getUrl()); throw new UnsupportedOperationException("Unsupported export redis service. url: " + invoker.getUrl());
} }
...@@ -64,8 +65,10 @@ public class RedisProtocol extends AbstractProtocol { ...@@ -64,8 +65,10 @@ public class RedisProtocol extends AbstractProtocol {
return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(url.getParameter(Constants.SERIALIZATION_KEY, "java")); return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(url.getParameter(Constants.SERIALIZATION_KEY, "java"));
} }
@Override
public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException { public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException {
try { try {
// 创建 GenericObjectPoolConfig 对象,设置配置
GenericObjectPoolConfig config = new GenericObjectPoolConfig(); GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setTestOnBorrow(url.getParameter("test.on.borrow", true)); config.setTestOnBorrow(url.getParameter("test.on.borrow", true));
config.setTestOnReturn(url.getParameter("test.on.return", false)); config.setTestOnReturn(url.getParameter("test.on.return", false));
...@@ -86,46 +89,64 @@ public class RedisProtocol extends AbstractProtocol { ...@@ -86,46 +89,64 @@ public class RedisProtocol extends AbstractProtocol {
config.setTimeBetweenEvictionRunsMillis(url.getParameter("time.between.eviction.runs.millis", 0)); config.setTimeBetweenEvictionRunsMillis(url.getParameter("time.between.eviction.runs.millis", 0));
if (url.getParameter("min.evictable.idle.time.millis", 0) > 0) if (url.getParameter("min.evictable.idle.time.millis", 0) > 0)
config.setMinEvictableIdleTimeMillis(url.getParameter("min.evictable.idle.time.millis", 0)); config.setMinEvictableIdleTimeMillis(url.getParameter("min.evictable.idle.time.millis", 0));
// 创建 JedisPool 对象
final JedisPool jedisPool = new JedisPool(config, url.getHost(), url.getPort(DEFAULT_PORT), final JedisPool jedisPool = new JedisPool(config, url.getHost(), url.getPort(DEFAULT_PORT),
url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT)); url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT));
// 处理方法名的映射
final int expiry = url.getParameter("expiry", 0); final int expiry = url.getParameter("expiry", 0);
final String get = url.getParameter("get", "get"); final String get = url.getParameter("get", "get");
final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set"); final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set");
final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete"); final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete");
// 创建 Invoker 对象
return new AbstractInvoker<T>(type, url) { return new AbstractInvoker<T>(type, url) {
protected Result doInvoke(Invocation invocation) throws Throwable {
@Override
protected Result doInvoke(Invocation invocation) {
Jedis resource = null; Jedis resource = null;
try { try {
// 获得 Redis Resource
resource = jedisPool.getResource(); resource = jedisPool.getResource();
// Redis get 指令
if (get.equals(invocation.getMethodName())) { if (get.equals(invocation.getMethodName())) {
if (invocation.getArguments().length != 1) { if (invocation.getArguments().length != 1) {
throw new IllegalArgumentException("The redis get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); throw new IllegalArgumentException("The redis get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
} }
// 获得值
byte[] value = resource.get(String.valueOf(invocation.getArguments()[0]).getBytes()); byte[] value = resource.get(String.valueOf(invocation.getArguments()[0]).getBytes());
if (value == null) { if (value == null) {
return new RpcResult(); return new RpcResult();
} }
// 反序列化
ObjectInput oin = getSerialization(url).deserialize(url, new ByteArrayInputStream(value)); ObjectInput oin = getSerialization(url).deserialize(url, new ByteArrayInputStream(value));
// 返回结果
return new RpcResult(oin.readObject()); return new RpcResult(oin.readObject());
// Redis set/put 指令
} else if (set.equals(invocation.getMethodName())) { } else if (set.equals(invocation.getMethodName())) {
if (invocation.getArguments().length != 2) { if (invocation.getArguments().length != 2) {
throw new IllegalArgumentException("The redis set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); throw new IllegalArgumentException("The redis set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
} }
// 序列化
byte[] key = String.valueOf(invocation.getArguments()[0]).getBytes(); byte[] key = String.valueOf(invocation.getArguments()[0]).getBytes();
ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream();
ObjectOutput value = getSerialization(url).serialize(url, output); ObjectOutput value = getSerialization(url).serialize(url, output);
value.writeObject(invocation.getArguments()[1]); value.writeObject(invocation.getArguments()[1]);
// 设置值
resource.set(key, output.toByteArray()); resource.set(key, output.toByteArray());
if (expiry > 1000) { if (expiry > 1000) {
resource.expire(key, expiry / 1000); resource.expire(key, expiry / 1000);
} }
// 返回结果
return new RpcResult(); return new RpcResult();
// Redis remote/delete 指令
} else if (delete.equals(invocation.getMethodName())) { } else if (delete.equals(invocation.getMethodName())) {
if (invocation.getArguments().length != 1) { if (invocation.getArguments().length != 1) {
throw new IllegalArgumentException("The redis delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); throw new IllegalArgumentException("The redis delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
} }
// 删除值
resource.del(String.valueOf(invocation.getArguments()[0]).getBytes()); resource.del(String.valueOf(invocation.getArguments()[0]).getBytes());
// 返回结果
return new RpcResult(); return new RpcResult();
} else { } else {
throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in redis service."); throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in redis service.");
...@@ -141,6 +162,7 @@ public class RedisProtocol extends AbstractProtocol { ...@@ -141,6 +162,7 @@ public class RedisProtocol extends AbstractProtocol {
} }
throw re; throw re;
} finally { } finally {
// 归还 Redis Resource
if (resource != null) { if (resource != null) {
try { try {
jedisPool.returnResource(resource); jedisPool.returnResource(resource);
...@@ -151,14 +173,18 @@ public class RedisProtocol extends AbstractProtocol { ...@@ -151,14 +173,18 @@ public class RedisProtocol extends AbstractProtocol {
} }
} }
@Override
public void destroy() { public void destroy() {
// 标记销毁
super.destroy(); super.destroy();
// 销毁 Redis Pool
try { try {
jedisPool.destroy(); jedisPool.destroy();
} catch (Throwable e) { } catch (Throwable e) {
logger.warn(e.getMessage(), e); logger.warn(e.getMessage(), e);
} }
} }
}; };
} catch (Throwable t) { } catch (Throwable t) {
throw new RpcException("Failed to refer redis service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t); throw new RpcException("Failed to refer redis service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t);
......
...@@ -35,9 +35,14 @@ import java.rmi.RemoteException; ...@@ -35,9 +35,14 @@ import java.rmi.RemoteException;
/** /**
* RmiProtocol. * RmiProtocol.
*
* RMI 协议实现类
*/ */
public class RmiProtocol extends AbstractProxyProtocol { public class RmiProtocol extends AbstractProxyProtocol {
/**
* 默认端口
*/
public static final int DEFAULT_PORT = 1099; public static final int DEFAULT_PORT = 1099;
public RmiProtocol() { public RmiProtocol() {
...@@ -48,7 +53,9 @@ public class RmiProtocol extends AbstractProxyProtocol { ...@@ -48,7 +53,9 @@ public class RmiProtocol extends AbstractProxyProtocol {
return DEFAULT_PORT; return DEFAULT_PORT;
} }
@Override
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException { protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
// 创建 RmiServiceExporter 对象
final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter(); final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
rmiServiceExporter.setRegistryPort(url.getPort()); rmiServiceExporter.setRegistryPort(url.getPort());
rmiServiceExporter.setServiceName(url.getPath()); rmiServiceExporter.setServiceName(url.getPath());
...@@ -59,6 +66,7 @@ public class RmiProtocol extends AbstractProxyProtocol { ...@@ -59,6 +66,7 @@ public class RmiProtocol extends AbstractProxyProtocol {
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RpcException(e.getMessage(), e); throw new RpcException(e.getMessage(), e);
} }
// 返回取消暴露的回调 Runnable
return new Runnable() { return new Runnable() {
public void run() { public void run() {
try { try {
...@@ -70,10 +78,13 @@ public class RmiProtocol extends AbstractProxyProtocol { ...@@ -70,10 +78,13 @@ public class RmiProtocol extends AbstractProxyProtocol {
}; };
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException { protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
// 创建 RmiProxyFactoryBean 对象
final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean(); final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
// RMI needs extra parameter since it uses customized remote invocation object // RMI needs extra parameter since it uses customized remote invocation object
// RMI传输时使用自定义的远程执行对象,从而传递额外的参数
if (url.getParameter(Constants.DUBBO_VERSION_KEY, Version.getVersion()).equals(Version.getVersion())) { if (url.getParameter(Constants.DUBBO_VERSION_KEY, Version.getVersion()).equals(Version.getVersion())) {
// Check dubbo version on provider, this feature only support // Check dubbo version on provider, this feature only support
rmiProxyFactoryBean.setRemoteInvocationFactory(new RemoteInvocationFactory() { rmiProxyFactoryBean.setRemoteInvocationFactory(new RemoteInvocationFactory() {
...@@ -82,15 +93,18 @@ public class RmiProtocol extends AbstractProxyProtocol { ...@@ -82,15 +93,18 @@ public class RmiProtocol extends AbstractProxyProtocol {
} }
}); });
} }
// 设置相关参数
rmiProxyFactoryBean.setServiceUrl(url.toIdentityString()); rmiProxyFactoryBean.setServiceUrl(url.toIdentityString());
rmiProxyFactoryBean.setServiceInterface(serviceType); rmiProxyFactoryBean.setServiceInterface(serviceType);
rmiProxyFactoryBean.setCacheStub(true); rmiProxyFactoryBean.setCacheStub(true);
rmiProxyFactoryBean.setLookupStubOnStartup(true); rmiProxyFactoryBean.setLookupStubOnStartup(true);
rmiProxyFactoryBean.setRefreshStubOnConnectFailure(true); rmiProxyFactoryBean.setRefreshStubOnConnectFailure(true);
rmiProxyFactoryBean.afterPropertiesSet(); rmiProxyFactoryBean.afterPropertiesSet();
// 创建 Service Proxy 对象
return (T) rmiProxyFactoryBean.getObject(); return (T) rmiProxyFactoryBean.getObject();
} }
@Override
protected int getErrorCode(Throwable e) { protected int getErrorCode(Throwable e) {
if (e instanceof RemoteAccessException) { if (e instanceof RemoteAccessException) {
e = e.getCause(); e = e.getCause();
......
...@@ -25,11 +25,15 @@ import java.util.HashMap; ...@@ -25,11 +25,15 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class RmiRemoteInvocation extends RemoteInvocation { public class RmiRemoteInvocation extends RemoteInvocation {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final String dubboAttachmentsAttrName = "dubbo.attachments"; private static final String dubboAttachmentsAttrName = "dubbo.attachments";
/** /**
* executed on consumer side * executed on consumer side
*
* 构造将在消费端执行
*/ */
public RmiRemoteInvocation(MethodInvocation methodInvocation) { public RmiRemoteInvocation(MethodInvocation methodInvocation) {
super(methodInvocation); super(methodInvocation);
...@@ -40,6 +44,8 @@ public class RmiRemoteInvocation extends RemoteInvocation { ...@@ -40,6 +44,8 @@ public class RmiRemoteInvocation extends RemoteInvocation {
* Need to restore context on provider side (Though context will be overridden by Invocation's attachment * Need to restore context on provider side (Though context will be overridden by Invocation's attachment
* when ContextFilter gets executed, we will restore the attachment when Invocation is constructed, check more * when ContextFilter gets executed, we will restore the attachment when Invocation is constructed, check more
* from {@link com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler} * from {@link com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler}
*
* 服务端执行时,重新放入上下文(虽然这时上下文在ContextFilter执行时将被Invocation的attachments覆盖,我们在Invocation构造时还原attachments, see InvokerInvocationHandler)
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
......
...@@ -50,17 +50,33 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -50,17 +50,33 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* WebServiceProtocol. * WebServiceProtocol.
*
* WebService 协议实现类
*/ */
public class WebServiceProtocol extends AbstractProxyProtocol { public class WebServiceProtocol extends AbstractProxyProtocol {
/**
* 默认服务器端口
*/
public static final int DEFAULT_PORT = 80; public static final int DEFAULT_PORT = 80;
/**
* Http 服务器集合
*
* key:ip:port
*/
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>(); private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
/**
* 《我眼中的CXF之Bus》http://jnn.iteye.com/blog/94746
* 《CXF BUS》https://blog.csdn.net/chen_fly2011/article/details/56664908
*/
private final ExtensionManagerBus bus = new ExtensionManagerBus(); private final ExtensionManagerBus bus = new ExtensionManagerBus();
/**
*
*/
private final HTTPTransportFactory transportFactory = new HTTPTransportFactory(); private final HTTPTransportFactory transportFactory = new HTTPTransportFactory();
/**
* HttpBinder$Adaptive 对象
*/
private HttpBinder httpBinder; private HttpBinder httpBinder;
public WebServiceProtocol() { public WebServiceProtocol() {
...@@ -76,13 +92,17 @@ public class WebServiceProtocol extends AbstractProxyProtocol { ...@@ -76,13 +92,17 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
return DEFAULT_PORT; return DEFAULT_PORT;
} }
@Override
protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException { protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
// 获得服务器地址
String addr = getAddr(url); String addr = getAddr(url);
// 获得 HttpServer 对象。若不存在,进行创建。
HttpServer httpServer = serverMap.get(addr); HttpServer httpServer = serverMap.get(addr);
if (httpServer == null) { if (httpServer == null) {
httpServer = httpBinder.bind(url, new WebServiceHandler()); httpServer = httpBinder.bind(url, new WebServiceHandler()); // WebServiceHandler
serverMap.put(addr, httpServer); serverMap.put(addr, httpServer);
} }
// 创建 ServerFactoryBean 对象
final ServerFactoryBean serverFactoryBean = new ServerFactoryBean(); final ServerFactoryBean serverFactoryBean = new ServerFactoryBean();
serverFactoryBean.setAddress(url.getAbsolutePath()); serverFactoryBean.setAddress(url.getAbsolutePath());
serverFactoryBean.setServiceClass(type); serverFactoryBean.setServiceClass(type);
...@@ -90,6 +110,7 @@ public class WebServiceProtocol extends AbstractProxyProtocol { ...@@ -90,6 +110,7 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
serverFactoryBean.setBus(bus); serverFactoryBean.setBus(bus);
serverFactoryBean.setDestinationFactory(transportFactory); serverFactoryBean.setDestinationFactory(transportFactory);
serverFactoryBean.create(); serverFactoryBean.create();
// 返回取消暴露的回调 Runnable
return new Runnable() { return new Runnable() {
public void run() { public void run() {
serverFactoryBean.destroy(); serverFactoryBean.destroy();
...@@ -97,13 +118,17 @@ public class WebServiceProtocol extends AbstractProxyProtocol { ...@@ -97,13 +118,17 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
}; };
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException { protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
// 创建 ClientProxyFactoryBean 对象
ClientProxyFactoryBean proxyFactoryBean = new ClientProxyFactoryBean(); ClientProxyFactoryBean proxyFactoryBean = new ClientProxyFactoryBean();
proxyFactoryBean.setAddress(url.setProtocol("http").toIdentityString()); proxyFactoryBean.setAddress(url.setProtocol("http").toIdentityString());
proxyFactoryBean.setServiceClass(serviceType); proxyFactoryBean.setServiceClass(serviceType);
proxyFactoryBean.setBus(bus); proxyFactoryBean.setBus(bus);
// 创建 Service Proxy 对象
T ref = (T) proxyFactoryBean.create(); T ref = (T) proxyFactoryBean.create();
// 设置超时相关属性
Client proxy = ClientProxy.getClient(ref); Client proxy = ClientProxy.getClient(ref);
HTTPConduit conduit = (HTTPConduit) proxy.getConduit(); HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy(); HTTPClientPolicy policy = new HTTPClientPolicy();
...@@ -113,6 +138,7 @@ public class WebServiceProtocol extends AbstractProxyProtocol { ...@@ -113,6 +138,7 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
return ref; return ref;
} }
@Override
protected int getErrorCode(Throwable e) { protected int getErrorCode(Throwable e) {
if (e instanceof Fault) { if (e instanceof Fault) {
e = e.getCause(); e = e.getCause();
...@@ -129,7 +155,9 @@ public class WebServiceProtocol extends AbstractProxyProtocol { ...@@ -129,7 +155,9 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
private volatile ServletController servletController; private volatile ServletController servletController;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// 创建 ServletController 对象,设置使用 DispatcherServlet 。
if (servletController == null) { if (servletController == null) {
HttpServlet httpServlet = DispatcherServlet.getInstance(); HttpServlet httpServlet = DispatcherServlet.getInstance();
if (httpServlet == null) { if (httpServlet == null) {
...@@ -142,7 +170,9 @@ public class WebServiceProtocol extends AbstractProxyProtocol { ...@@ -142,7 +170,9 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
} }
} }
} }
// 设置调用方地址
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort()); RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
// 执行调用
servletController.invoke(request, response); servletController.invoke(request, response);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册