下面,咱们的思路是,先基于Dubbo封装的Hessian协议,实现提供方服务和消费方调用服务,双方必须都使用Dubbo来开发;而后,基于Dubbo封装的Hessian协议实现提供方服务,而后服务消费方使用标准的Hessian接口来进行远程调用,分别使用Java和Python语言来实现。并且,咱们实现的提供方服务经过Tomcat发布到服务注册中心。
首先,使用Java语言定义一个搜索服务的接口,代码以下所示:html
1 |
package org.shirdrn.platform.dubbo.service.rpc.api; |
2 |
3 |
public interface SolrSearchService { |
4 |
String search(String collection, String q, String type, int start, int rows); |
5 |
} |
上面接口提供了搜索远程调用功能。java
基于Dubbo的Hessian协议实现提供方服务python
提供方实现基于Dubbo封装的Hessian协议,实现接口SolrSearchService,实现代码以下所示:nginx
01 |
package org.shirdrn.platform.dubbo.service.rpc.server; |
02 |
03 |
import java.io.IOException; |
04 |
import java.util.HashMap; |
05 |
import java.util.Map; |
06 |
07 |
import org.apache.commons.logging.Log; |
08 |
import org.apache.commons.logging.LogFactory; |
09 |
import org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService; |
10 |
import org.shirdrn.platform.dubbo.service.rpc.utils.QueryPostClient; |
11 |
import org.springframework.context.support.ClassPathXmlApplicationContext; |
12 |
13 |
public class SolrSearchServer implements SolrSearchService { |
14 |
15 |
private static final Log LOG = LogFactory.getLog(SolrSearchServer. class ); |
16 |
private String baseUrl; |
17 |
private final QueryPostClient postClient; |
18 |
private static final Map<String, FormatHandler> handlers = new HashMap<String, FormatHandler>( 0 ); |
19 |
static { |
20 |
handlers.put( "xml" , new FormatHandler() { |
21 |
public String format() { |
22 |
return "&wt=xml" ; |
23 |
} |
24 |
}); |
25 |
handlers.put( "json" , new FormatHandler() { |
26 |
public String format() { |
27 |
return "&wt=json" ; |
28 |
} |
29 |
}); |
30 |
} |
31 |
32 |
public SolrSearchServer() { |
33 |
super (); |
34 |
postClient = QueryPostClient.newIndexingClient( null ); |
35 |
} |
36 |
37 |
public void setBaseUrl(String baseUrl) { |
38 |
this .baseUrl = baseUrl; |
39 |
} |
40 |
41 |
public String search(String collection, String q, String type, int start, int rows) { |
42 |
StringBuffer url = new StringBuffer(); |
43 |
url.append(baseUrl).append(collection).append( "/select?" ).append(q); |
44 |
url.append( "&start=" ).append(start).append( "&rows=" ).append(rows); |
45 |
url.append(handlers.get(type.toLowerCase()).format()); |
46 |
LOG.info( "[REQ] " + url.toString()); |
47 |
return postClient.request(url.toString()); |
48 |
} |
49 |
50 |
interface FormatHandler { |
51 |
String format(); |
52 |
} |
53 |
} |
由于考虑到后面要使用标准Hessian接口来调用,这里接口方法参数所有使用内置标准类型。而后,咱们使用Dubbo的配置文件进行配置,文件search-provider.xml的内容以下所示:git
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
03 |
< beans xmlns = "http://www.springframework.org/schema/beans" |
04 |
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo = "http://code.alibabatech.com/schema/dubbo" |
05 |
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd |
07 |
08 |
< dubbo:application name = "search-provider" /> |
09 |
< dubbo:registry |
10 |
address = "zookeeper://slave1:2188?backup=slave3:2188,slave4:2188" /> |
11 |
< dubbo:protocol name = "hessian" port = "8080" server = "servlet" /> |
12 |
< bean id = "searchService" |
13 |
class = "org.shirdrn.platform.dubbo.service.rpc.server.SolrSearchServer" > |
14 |
< property name = "baseUrl" value = "http://nginx-lbserver/solr-cloud/" /> |
15 |
</ bean > |
16 |
< dubbo:service |
17 |
interface = "org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService" |
18 |
ref = "searchService" path = "http_dubbo/search" /> |
19 |
20 |
</ beans > |
由于使用Tomcat发布提供方服务,因此咱们须要实现Spring的org.springframework.web.context.ContextLoader来初始化应用上下文(基于Spring的IoC容器来管理服务对象)。实现类SearchContextLoader代码以下所示:github
01 |
package org.shirdrn.platform.dubbo.context; |
02 |
03 |
import javax.servlet.ServletContextEvent; |
04 |
import javax.servlet.ServletContextListener; |
05 |
06 |
import org.shirdrn.platform.dubbo.service.rpc.server.SolrSearchServer; |
07 |
import org.springframework.context.support.ClassPathXmlApplicationContext; |
08 |
import org.springframework.web.context.ContextLoader; |
09 |
10 |
public class SearchContextLoader extends ContextLoader implements ServletContextListener { |
11 |
12 |
@Override |
13 |
public void contextDestroyed(ServletContextEvent arg0) { |
14 |
// TODO Auto-generated method stub |
15 |
16 |
} |
17 |
18 |
@Override |
19 |
public void contextInitialized(ServletContextEvent arg0) { |
20 |
String config = arg0.getServletContext().getInitParameter( "contextConfigLocation" ); |
21 |
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config); |
22 |
context.start(); |
23 |
} |
24 |
25 |
} |
最后,配置Web应用部署描述符文件,web.xml内容以下所示:web
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
< web-app id = "WebApp_ID" version = "2.4" |
03 |
xmlns = "http://java.sun.com/xml/ns/j2ee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" |
04 |
xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > |
05 |
< display-name >http_dubbo</ display-name > |
06 |
07 |
< listener > |
08 |
< listener-class >org.shirdrn.platform.dubbo.context.SearchContextLoader</ listener-class > |
09 |
</ listener > |
10 |
< context-param > |
11 |
< param-name >contextConfigLocation</ param-name > |
12 |
< param-value >classpath:search-provider.xml</ param-value > |
13 |
</ context-param > |
14 |
15 |
< servlet > |
16 |
< servlet-name >search</ servlet-name > |
17 |
< servlet-class >com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</ servlet-class > |
18 |
< init-param > |
19 |
< param-name >home-class</ param-name > |
20 |
< param-value >org.shirdrn.platform.dubbo.service.rpc.server.SolrSearchServer</ param-value > |
21 |
</ init-param > |
22 |
< init-param > |
23 |
< param-name >home-api</ param-name > |
24 |
< param-value >org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService</ param-value > |
25 |
</ init-param > |
26 |
< load-on-startup >1</ load-on-startup > |
27 |
</ servlet > |
28 |
< servlet-mapping > |
29 |
< servlet-name >search</ servlet-name > |
30 |
< url-pattern >/search</ url-pattern > |
31 |
</ servlet-mapping > |
32 |
33 |
< welcome-file-list > |
34 |
< welcome-file >index.html</ welcome-file > |
35 |
< welcome-file >index.htm</ welcome-file > |
36 |
< welcome-file >index.jsp</ welcome-file > |
37 |
< welcome-file >default.html</ welcome-file > |
38 |
< welcome-file >default.htm</ welcome-file > |
39 |
< welcome-file >default.jsp</ welcome-file > |
40 |
</ welcome-file-list > |
41 |
</ web-app > |
启动Tomcat之后,就能够将提供方服务发布到服务注册中心,这里服务注册中心咱们使用的是ZooKeeper集群,能够参考上面Dubbo配置文件search-provider.xml的配置内容。spring
下面,咱们经过两种方式来调用已经注册到服务注册中心的服务。apache
服务消费方,经过Dubbo配置文件来指定注册到注册中心的服务,配置文件search-consumer.xml的内容,以下所示:编程
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
03 |
< beans xmlns = "http://www.springframework.org/schema/beans" |
04 |
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo = "http://code.alibabatech.com/schema/dubbo" |
05 |
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd |
07 |
08 |
< dubbo:application name = "search-consumer" /> |
09 |
< dubbo:registry |
10 |
address = "zookeeper://slave1:2188?backup=slave3:2188,slave4:2188" /> |
11 |
< dubbo:reference id = "searchService" |
12 |
interface = "org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService" /> |
13 |
14 |
</ beans > |
而后,使用Java实现远程调用,实现代码以下所示:
01 |
package org.shirdrn.platform.dubbo.service.rpc.client; |
02 |
03 |
import java.util.concurrent.Callable; |
04 |
import java.util.concurrent.Future; |
05 |
06 |
import org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService; |
07 |
import org.springframework.beans.BeansException; |
08 |
import org.springframework.context.support.AbstractXmlApplicationContext; |
09 |
import org.springframework.context.support.ClassPathXmlApplicationContext; |
10 |
11 |
import com.alibaba.dubbo.rpc.RpcContext; |
12 |