下面,咱們的思路是,先基於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 |