高級(jí)框架第一天RPC:遠(yuǎn)程過(guò)程調(diào)用

RPC:遠(yuǎn)程過(guò)程調(diào)用

主要內(nèi)容

1.項(xiàng)目結(jié)構(gòu)變化

2.RPC簡(jiǎn)介

3.RMI實(shí)現(xiàn)RPC

4.HttpClient實(shí)現(xiàn)RPC

5.Zookeeper安裝

6.Zookeeper客戶端常用命令

7.向Zookeeper中注冊(cè)內(nèi)容

8.從Zookeeper中發(fā)現(xiàn)內(nèi)容

9.手寫(xiě)RPC框架

一.今天學(xué)什么?為什么講?

Dubbo是RPC的一個(gè)框架.

二.項(xiàng)目架構(gòu)變化

1.單體架構(gòu)

1.1架構(gòu)圖

單體架構(gòu)就是一個(gè)項(xiàng)目里面包含這個(gè)項(xiàng)目中全部代碼.一個(gè)應(yīng)用搞定全部功能.

DNS服務(wù)器可以是單映射,也可以配置多個(gè)映射.

1.2軟阿基代碼結(jié)構(gòu)

在單體架構(gòu)項(xiàng)目中,團(tuán)隊(duì)都是通過(guò)包(package)進(jìn)行區(qū)分每個(gè)模塊

總體包結(jié)構(gòu):com.bjsxt.*.分層包

項(xiàng)目名:

? ? --com

? ? ? ? --bjsxt

? ? ? ? ? ? --common

? ? ? ? ? ? --utils

? ? ? ? --user

? ? ? ? ? ? --controller

? ? ? ? ? ? --service

? ? ? ? ? ? --mapper

? ? ????--sys

? ? ? ? ? ? --controller

? ? ? ? ? ? --service

? ? ? ? ? ? --mapper

1.3優(yōu)缺點(diǎn)

1.3.1優(yōu)點(diǎn)

部署簡(jiǎn)單,維護(hù)方便,開(kāi)發(fā)成本低

1.3.2缺點(diǎn)

當(dāng)項(xiàng)目規(guī)模大,用戶訪問(wèn)頻率高,并發(fā)量大,數(shù)據(jù)量大時(shí),會(huì)大大降低程序執(zhí)行效率,甚至出現(xiàn)服務(wù)器宕機(jī)等情況

1.4適用項(xiàng)目

傳統(tǒng)管理項(xiàng)目,小型互聯(lián)網(wǎng)項(xiàng)目

2.分布式架構(gòu)

2.1架構(gòu)圖(簡(jiǎn)易版)

分布式架構(gòu)會(huì)把一個(gè)項(xiàng)目按照特定要求(多按照模塊或功能)拆分成多個(gè)項(xiàng)目,每個(gè)項(xiàng)目分別部署到不同的服務(wù)器上.

2.2軟件代碼結(jié)構(gòu)

項(xiàng)目1:

? ? --com.bjsxt.xxx

? ? ? ? --controller

? ? ? ? --service

? ? ? ? --mapper

項(xiàng)目2:

? ? --com.bjsxt.mmm

? ? ? ? --controller

? ? ? ? --service

? ? ? ? --mapper

2.3優(yōu)缺點(diǎn)

2.3.1優(yōu)點(diǎn)

增大了系統(tǒng)可用性.減少單點(diǎn)故障,導(dǎo)致整個(gè)應(yīng)用不可用

增加重用性.因?yàn)槟K化,所以重用性更高.高內(nèi)聚,低耦合

增加可擴(kuò)展性.有新的模塊增加新的項(xiàng)目即可

增加每個(gè)模塊的負(fù)載能力.因?yàn)槊總€(gè)模塊都是一個(gè)項(xiàng)目,所以每個(gè)模塊的負(fù)載能力更強(qiáng)

2.3.2缺點(diǎn)

成本更高.因?yàn)榧夹g(shù)多,難,所以開(kāi)大成本,時(shí)間成本,維護(hù)成本都在變高

架構(gòu)更加復(fù)雜

整體響應(yīng)之間變長(zhǎng),一些業(yè)務(wù)需要多項(xiàng)目通信后給出結(jié)果

通吐量更大.吞吐量=請(qǐng)求數(shù)/秒

2.4適用項(xiàng)目

中,大型互聯(lián)網(wǎng)項(xiàng)目.客戶多,數(shù)據(jù)多,訪問(wèn)并發(fā)高,壓力大,吞吐量高

2.5待解決問(wèn)題

分布式架構(gòu)中各個(gè)模塊如何進(jìn)行通信?

可以使用Http協(xié)議,也可以石紅RPC協(xié)議通信,也可以使用其他的通信方式.我們本階段使用的是RPC協(xié)議,因?yàn)樗菻TTP更適合項(xiàng)目?jī)?nèi)部通信

三.RPC簡(jiǎn)介

1.RFC

RFC(Request For Comments)是由互聯(lián)網(wǎng)工程任務(wù)組(IEIF)發(fā)布的文件集.文件集中每個(gè)文件都有自己唯一編號(hào).例如:rfc1831.目前RFC文件由互聯(lián)網(wǎng)協(xié)會(huì)(Internet Society,ISOC)贊助發(fā)行

? ? RPC就收集在RFC1831中.可以通過(guò)下面網(wǎng)址查看:

https://datatracker.ietf.org/doc/rfc1831/

2.RPC

RPC在rgc1831中收錄,RPC(Remote Procedure Call)遠(yuǎn)程過(guò)程調(diào)用協(xié)議

RPC協(xié)議規(guī)定允許互聯(lián)網(wǎng)中一臺(tái)主機(jī)程序調(diào)動(dòng)另一臺(tái)主機(jī)程序,而程序員無(wú)需對(duì)這個(gè)交互過(guò)程進(jìn)行編程.在RPC協(xié)議中強(qiáng)調(diào)當(dāng)A程序調(diào)用B程序中功能或方法時(shí),A是不知道B中方法具體實(shí)現(xiàn)的

RPC是上層協(xié)議,底層可以基于TCP協(xié)議,也可以基于HTTP協(xié)議.一般我們說(shuō)RPC都是基于RPC的具體實(shí)現(xiàn),如:Dubbo框架.從廣義上講只要是滿足網(wǎng)絡(luò)中進(jìn)行通信調(diào)用都統(tǒng)稱為RPC,甚至HTTP協(xié)議都可以說(shuō)是RPC的具體實(shí)現(xiàn),但是具體分析看來(lái)RPC協(xié)議要比HTTP協(xié)議更加高效,基于RPC的框架功能更多

RPC協(xié)議是基于分布式架構(gòu)而出現(xiàn)的,所以RPC在分布式項(xiàng)目中有著得天獨(dú)厚的優(yōu)勢(shì)

3.RPC和HTTP對(duì)比

3.1具體實(shí)現(xiàn)

RPC:可以基于TCP協(xié)議,也可以基于HTTP協(xié)議

HTTP:基于HTTP協(xié)議

3.2效率

RPC:自定義具體實(shí)現(xiàn)可以減少很多無(wú)用的報(bào)文內(nèi)容,使得報(bào)文體積更小

HTTP:如果是HTTP1.1報(bào)文中很多內(nèi)容都是無(wú)用的.如果是HTTP2.0以后和RPC相差不大,比RPC少的可能就是一些服務(wù)治理等功能

3.3連接方式

RPC:長(zhǎng)鏈接支持

HTTP:每次連接都是3次握手(斷開(kāi)連接為4次揮手)

3.4性能

RPC可以基于很多序列化方式.如:thrift

HTTP主要是通過(guò)JSON,序列化和方序列化效率更低

3.5注冊(cè)中心

RPC:一般RPC框架都帶有注冊(cè)中心

HTTP:都是直連

3.6負(fù)載均衡

RPC:絕大多數(shù)RPC框架都帶有負(fù)載均衡測(cè)量

HTTP:一般都需要借助第三方工具.如:nginx

3.7綜合結(jié)論

RPC框架一般都帶有豐富的服務(wù)治理等功能,更適合企業(yè)內(nèi)部接口調(diào)用.而HTTP更適合多平臺(tái)之間相互調(diào)用

四.HttpClient實(shí)現(xiàn)RPC

1.HttpClient簡(jiǎn)介

在JDK中java.net包下提供了用戶HTTP訪問(wèn)的基本功能,但是它缺少靈活性或許多應(yīng)用所需要的功能

HttpClient起初是Apache Jackarta Common的子項(xiàng)目.用來(lái)提供高效的,最新的,功能豐富的支持HTTP協(xié)議的客戶端編程工具包,并且他支持HTTP協(xié)議最新的版本.2007年成為頂級(jí)項(xiàng)目

通俗解釋:HttpClient可以實(shí)現(xiàn)Java代碼完成標(biāo)準(zhǔn)HTTP請(qǐng)求及響應(yīng)

2.代碼實(shí)現(xiàn)

2.1服務(wù)端

新建項(xiàng)目HttpClientServer

2.1.1新建控制器

com.bjsxt.controller.DemoController

@Controller

public class DemoController{

? ? @RequestMapping("/demo")

? ? @ResponseBody

? ? public String demo(String param){

? ? ? ? return "demo"+param;

????}

}

2.1.2新建啟動(dòng)器

com.bjsxt.HttpClientServerApplication

@SpringBootApplication

public class HttpClientServerApplication{

? ? public static void main(String[] args){

? ? ? ? SpringApplication.run(HttpClientServerApplication.class,args);

????}

}

2.2客戶端

新建HttpClientDemo項(xiàng)目

2.2.1添加依賴

<dependencies>

? ? <dependency>

? ? ? ? <groupId>org.apache.httpcomponents</groupId>

? ? ? ? <artifactId>httpclient</artifactId>

? ? ? ? <version>4.5.10</version>

????</dependency>

</dependencies>

2.2.2新建類

新建com.bsjxt.HttpClientDemo,編寫(xiě)主方法

2.2.2.1使用POST方法訪問(wèn)

public class HttpClientDemo{

? ? public static void main(String[] args){

? ? ? ? try{

? ? ? ? ? ? CloseableHttpClient httpClient = HttpClients.createDefault();

? ? ? ? ? ? HttpPost post = new HttpPost("http://localhost:8080/demo");

? ? ? ? ? ? HttpEntity httpEntity = null;

? ? ? ? ? ? List<NameValuePair>params = new ArrayList<>();

? ? ? ? ? ? params.add(new BasicNameValuePair("param","123"));

? ? ? ? ? ? StringEntity entity = new UrlEncodedFormEntity(params,"utf-8");

? ? ? ? ? ? post.setEntity(entity);

? ? ? ? ? ? CloseableHttpResponse response = httpClient.execute(post);

? ? ? ? ? ? String result = EntityUtils.toString(response.getEntity());

? ? ? ? ? ? System.out.println(result);

? ? ? ? ? ? response.close();

? ? ? ? ? ? httpClient.close();

????????}catcha(IOException e){

? ? ? ? ? ? e.printStackTrace();

????????}

????}

}

2.2.2.2使用GET方式訪問(wèn)

public static void main(String[] args){

? ? try{

? ? ? ? CloseableHttpClient httpClient = HttpClients.createDefault();

? ? ? ? URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/demo");

? ? ? ? uriBuilder.addParameter("param","get123");

? ? ? ? HttpGet get = new HttpGet(uriBuilder.build());

? ? ? ? CloseableHttpResponse response = httpClient.execute(get);

? ? ? ? String result = EntityUtils.toString(response.getEntity(),"utf-8");

? ? ? ? System.out.println(result);

? ? ? ? response.close();

? ? ? ? httpClient.close();

????}catch(URISyntaxException e){

? ? ? ? e.printStackTrace();

????}catch(IOException e){

? ? ? ? e.printlnStackTrace();

????}

}

3.HttpClient請(qǐng)求包含JSON

3.1java代理實(shí)現(xiàn)

public class HttpClientDemo{

? ? public static void main(Stirng[] args){

? ? ? ? try{

? ? ? ? ? ? CloseableHttpClient httpClient = HttpClients.createDefault();

? ? ? ? ? ? HttpPost post = new HttpPost("http://localhost:8080/demo");

? ? ? ? ? ? HttpEntity httpEntity = null;

? ? ? ? ? ? String json = "{}";

? ? ? ? ? ? StringEntity entity = new StringEntity(json,ContentType.APPLICATION_JSON);

? ? ? ? ? ? post.setEntity(entity);

? ? ? ? ? ? CloseableHttpResponse response = httpClient.execute(post);

? ? ? ? ? ? String result - EntityUtils.toString(response.getEntity());

? ? ? ? ? ? System.out.println(result);

? ? ? ? ? ? response.close();

? ? ? ? ? ? httpClient.close();

????????}catch(IOException e){

? ? ? ? ? ? e.printStackTrace();

????????}

????}

}

4.服務(wù)端控制器接口參數(shù)

@RequestBody把請(qǐng)求體中六數(shù)據(jù)轉(zhuǎn)換為指定的對(duì)象.多用在請(qǐng)求體參數(shù)是json數(shù)據(jù)且請(qǐng)求的Content-Type="application/json"

@RequestMapping("/demo4")

@ResponseBody

public String demo4(@RequestBody List<People>list){

? ? System.out.println(list);

? ? return list.toString();

}

5.Jackson用法

5.1把對(duì)象轉(zhuǎn)換為json字符串

ObjectMapper objectMapper = new ObjectMapper();

People peo = new People();

String jsonStr = objectMapper.writeValueAsString(peo);

5.2把json字符串轉(zhuǎn)換為對(duì)象

ObjectMapper objectMapper= new ObjectMapper();

People peo = objectMapper.readValue(jsonStr,People.class);

5.3把json字符串轉(zhuǎn)換為L(zhǎng)ist集合

ObjectMapper objectMapper = new ObjectMapper();

JavaType javaType = objectMapper.getTypeFactory().constructParametericType(List.class,People.class);

List<People> list = objectMapper.readValue(jsonStr,javaType);

6.Ajax發(fā)送json參數(shù)寫(xiě)法

var json = '[{"id":123,"name":"bjsxt"},{"id":123,"name:"bjsxt"}]';

$.ajax({

? ? url:'/demo5',

? ? success:function(data}{

? ? ? ? alert(data);

? ? ? ? for(var i=0; i<data.length; i++){

????????????alert(data[i].id+"? "+data[i].name);

????????}

????},

? ? contentType:'application/json',//請(qǐng)求體中參數(shù)類型

? ? dataType:'json',//響應(yīng)內(nèi)容類型

? ? data:json

});

7.跨域

跨域:協(xié)議,端口,ip中只要有一個(gè)不同就是跨域請(qǐng)求

同源策略:瀏覽器默認(rèn)只允許ajax訪問(wèn)同源(協(xié)議,ip,端口都相同)內(nèi)容

解決同源策略:

在控制器接口上天啊及@CrossOrigin.表示允許跨域.本質(zhì)在響應(yīng)頭中添加

Access-Control-Allow-Origin:*

@RequestMapping("/demo5")

@ResponseBody

@CrossOrigin

public List<People>demo5(@RequestBody List<People>list){

? ? System.put.println(list);

? ? return list;

}

五.RMI實(shí)現(xiàn)RPC

1.RMI簡(jiǎn)介

RMI(Remote Method Invocation)遠(yuǎn)程方法調(diào)用

RMI是從JDK1.2推出的功能,它可以實(shí)現(xiàn)在一個(gè)java應(yīng)用中可以像調(diào)用本地方法一樣調(diào)用另一個(gè)服務(wù)器中java應(yīng)用(JVM)中的內(nèi)容

RMI是java語(yǔ)言的遠(yuǎn)程調(diào)用,無(wú)法實(shí)現(xiàn)跨語(yǔ)言

2.執(zhí)行流程

Registry(注冊(cè)表)是防止所有服務(wù)器對(duì)象的命名空間.每次服務(wù)端創(chuàng)建一個(gè)對(duì)象時(shí),它都會(huì)使用bind()或rebind()方法注冊(cè)該對(duì)象.這些是使用稱為名稱的唯一名稱注冊(cè)的.

要調(diào)用遠(yuǎn)程對(duì)象,客戶端需要該對(duì)象的引用.即通過(guò)服務(wù)端綁定的名稱從注冊(cè)表中獲取對(duì)象(lookup()方法)

3.API介紹

3.1Remote

java.rmi.Remote定義了此接口為遠(yuǎn)程調(diào)用接口.如果接口被外部調(diào)用,需要繼承次接口

3.2RemoteException

java.rmi.RemoteException

繼承了Remote接口,如果方法是允許被遠(yuǎn)程調(diào)用的,需要拋出此異常

3.3UnicastRemoteObject

java.rmi.server.UnicastRemoteObject

此類實(shí)現(xiàn)了Remote接口和Serializable接口

自定義接口實(shí)現(xiàn)類除了實(shí)現(xiàn)自定義接口還需要繼承此類

3.4LocateRegistry

java.rmi.registry.LocateRegistry

可以通過(guò)LocateRegistry子本機(jī)上創(chuàng)建Registry,通過(guò)特定的端口就可以訪問(wèn)這個(gè)Registry

3.5Naming

java.rmi.Naming

Naming定義了發(fā)布內(nèi)容可訪問(wèn)RMI名稱.也是通過(guò)Naming獲取到指定的遠(yuǎn)程方法

4.代碼實(shí)現(xiàn)

4.1服務(wù)端創(chuàng)建

創(chuàng)建RmiServer項(xiàng)目

4.1.1編寫(xiě)接口

com.bjsxt.service.DemoService編寫(xiě)

public interface DemoService extends Remote{

? ? String demo(String demo)throws RemoteException;

}

4.1.2.編寫(xiě)實(shí)現(xiàn)類

com.bsjxt.service.impl.DemoServiceImpl編寫(xiě)

注意:

? ? 構(gòu)造方法是public的.默認(rèn)生成protected

public class DemoServiceImpl extends UnicastRemoteObject implements DemoService{

? ? public DemoServiceImpl() throws RemoteException{}

? ? @Override

? ? public String demo(String demo)throws RemoteException{

? ? ? ? return demo+"123";

????}

}

4.1.3編寫(xiě)主方法

編寫(xiě)com.bjsxt.DemoService類,生成主方法

public class DemoServer{

? ? public static void main(String[] args){

? ? ? ? try{

? ? ? ? ? ? DemoService demoService = new DemoServiceImpl();

? ? ? ? ? ? LocateRegistry.createRegistry(8888);

? ? ? ? ? ? Naming.bind("rmi://localhsot:8888/demoService",demoService);

????????}catch(RemoteException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(AlreadyBoundException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(malformedURLException){

? ? ? ? ? ? e.printStackTrace();

????????}

????}

}

4.1.4運(yùn)行項(xiàng)目

運(yùn)行項(xiàng)目后,項(xiàng)目一直處于啟動(dòng)狀態(tài),表示可以遠(yuǎn)程訪問(wèn)此項(xiàng)目中的遠(yuǎn)程方法

4.2創(chuàng)建客戶端代碼

創(chuàng)建項(xiàng)目RmiClient

4.2.1復(fù)制服務(wù)端接口

把服務(wù)端com.bjsxt.service.DemoService粘貼到項(xiàng)目中

注意:復(fù)制代碼僅為快速完成案例,學(xué)習(xí)技術(shù),在商業(yè)開(kāi)發(fā)中,DemoService接口應(yīng)該使用獨(dú)立的工程定義,并在服務(wù)端和客戶端工程中通過(guò)依賴的方式引入

4.2.2創(chuàng)建主方法類

新建com.bjsxt.DemoClient

public class DemoClient{

? ? public static void main(String[] args){

? ? ? ? try{

? ? ? ? ? ? DemoService demoService = (DemoService)Naming.lookup("rmi://localhost:8888/demoService");

? ? ? ? ? ? String result = demoService.demo("demo34");

? ? ? ? ? ? System.out.println(result);

????????}catch(NotBoundException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(MalformedURLException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(RemoteException e){

? ? ? ? ? ? e.printStackTrace();

????????}

????}

}

六.Zookeeper安裝

七.常用命令

八.向Zookeeper中注冊(cè)內(nèi)容

先進(jìn)項(xiàng)目ZookeeperClient

1.創(chuàng)建/demo節(jié)點(diǎn)

使用zookeeper的客戶端命令工具創(chuàng)建/demo

./zkCli.sh

create /demo

2.添加依賴

<dependencies>

? ? <dependency>

? ? ? ? <groupId>org.apache.zookeeper</groupId>

? ? ? ? <artifactId>zookeeper</artifactId>

? ? ? ? <version>3.5.5</version>

????</dependency>

</dependencies>

3.編寫(xiě)代碼

創(chuàng)建類com.bjsxt.MyApp

ZooDefs.Ids.OPEN-ACL_UNSAFE表示權(quán)限

CreateMode.PERSISTENT_SEQUENTIAL永久存儲(chǔ),文件內(nèi)容編寫(xiě)遞增

public static void main(String[] args){

? ? try{

? ? ? ? Zookeeper zookeeper = new Zookeeper("192.168.232.132:2181",60000,new Watcher(){;

? ??????????@Override

? ? ? ? ????public void process(WatcherEvent watchedEvent){

????????????????System.out.println("獲取連接");

????????????}

? ? });

? ? String content = zookeeper.create("/demo/nn","content".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT_SEQUENTIAL);

? ? System.out.println("content"+content);

????}catch(IOException e){

? ? ? ? e.printStackTrace();

????}catch(KeeperException e){

? ? ? ? e.printStackTrace();

????}catch(InterruptedException e){

? ? ? ? e.printStackTrace();

????}

}

4.查看上傳數(shù)據(jù)

ls -R /? ? 查看列表

get /demo/nn000000002? ? ?查看內(nèi)容

九.從zookeeper中發(fā)現(xiàn)內(nèi)容

在原有項(xiàng)目中新建一個(gè)類,類中編寫(xiě)主方法

public static void main(String[] args){

? ? try{

? ? ? ? Zookeeper zookeeper = new Zookeeper("192.168.232.132:2181",60000,new Watcher(){

? ? ? ? ? ? @Override

? ? ? ? ? ? public void process(WatchedEvent watchedEvent){

? ? ? ? ? ? ? ? System.out.println("獲取連接");

????????????}

????????});

? ? ? ? //獲取列表

? ? ? ? List<String>list = zookeeper.getChildren("/demo",false);

? ? ? ? for(String child:list){

? ? ? ? ? ? byte[] result = zookeeper.getData("/demo/"+child,false,null);

? ? ? ? ? ? Ssytem.out.println(new String(result));

????????}

????}catch(IOException e){

? ? ? ? e.printStackTrace();

????}catch(KeeperException e){

? ? ? ? e.printStackTrace();

????}catch(InterruptedException e){

? ? ? ? e.printStackTrace();

????}

}

十.手寫(xiě)RPC框架

使用Zookeeper作為注冊(cè)中心,RMI作為連接技術(shù),手寫(xiě)RPC框架

1.創(chuàng)建父項(xiàng)目ParentDemo

包含3個(gè)集合子項(xiàng)目

? ? service:包含被serviceImpl和consumer依賴的接口

? ? serviceImpl:provider提供的服務(wù)內(nèi)容

? ? consumer:消費(fèi)者,調(diào)用服務(wù)內(nèi)容

2.在父項(xiàng)目中添加依賴

<parent>

? ? <groupId>org.springframework.boot<groupId>

? ? <artifactId>spring-boot-starter-parent</artifactId>

? ? <version>2.1.10.RELEASE</version>

</parent>

<dependencies>

? ? <dependency>

? ? ? ? <groupId>org.springframework.boot</groupId>

? ? ? ? <artifactId>spring-boot-starter-web</artifactId>

????</dependency>

? ? <dependency>

? ? ? ? <groupId>org.apache.zookeeper</groupId>

? ? ? ? <aritfactId>zookeeper</artifactId>

? ? ? ? <version>3.5.5</version>

????</dependency>

</dependencies>

3.創(chuàng)建service項(xiàng)目

項(xiàng)目結(jié)構(gòu)如下:此項(xiàng)目中重點(diǎn)編寫(xiě)需要被兩個(gè)項(xiàng)目依賴的接口

4.創(chuàng)建DemoService接口

創(chuàng)建com.bjsxt.DemoService,具體內(nèi)容如下

public interface DemoService extends Remote{

? ? String demo(String param)throws RemoteException;

}

5.創(chuàng)建serviceImpl項(xiàng)目

此項(xiàng)目編寫(xiě)接口具體實(shí)現(xiàn),RMI服務(wù)發(fā)布和把信息發(fā)送到Zookeeper中

項(xiàng)目結(jié)構(gòu)如下:

在pom.xml中添加對(duì)service項(xiàng)目的依賴

<dependencies>

? ? <dependency>

? ? ? ? <artifactId>service</artifactId>

? ? ? ? <groupId>com.bjsxt</groupId>

? ? ? ? <version>1.0-SNAPSHOT</version>

????</dependency>

</dependencies>

6.創(chuàng)建DemoServiceImpl

創(chuàng)建com.bjsxt.service.impl.DemoServiceImpl

public class DemoServiceImpl extends UnicastRemoteObject implements DemoService{

? ? public DemoServiceImpl()throws RemoteException{

????}

? ? @Override

? ? public String demo(String param)throws RemoteException{

? ? ? ? return param+"123";

? ? }

}

7.創(chuàng)建RmiRun

創(chuàng)建com.bsjxt.RmiRun.實(shí)現(xiàn)RMI服務(wù)的發(fā)布和Zookeeper消息的發(fā)布

public class RmiRun{

? ? public static void main(String[] args){

? ? ? ? try{

? ? ? ? ? ? DemoService demoService = new DemoServiceImpl();

? ? ? ? ? ? LocateRegistry.createRegistry(8888);

? ? ? ? ? ? String url = "rmi://localhsot:8888/demoService";

? ? ? ? ? ? Naming.bind(url,demoService);

? ? ? ? ? ? Zookeeper zookeeper = new Zookeeper("192.168.232.132:2181",60000,new Watcher(){

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public void process(WatcherEvent watchedEvent){

? ? ? ? ? ? ? ? ? ? Ssytem.out.println("獲取連接");

????????????????}

????????????});

? ? ? ? ? ? String content = zookeeper.create("/demo/demoService",url.getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);

? ? ? ? ? ? System.out.println("服務(wù)發(fā)布成功...");

????????}catch(AlreadyBoundException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(IOException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(KeeperException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(InterruptedException e){

? ? ? ? ? ? e.printStackTrace();

????????}

????}

}

8.創(chuàng)建Consumer項(xiàng)目

新建consumer項(xiàng)目,此項(xiàng)目需要從zookeeper中獲取rmi信息,并調(diào)用rmi服務(wù)

在pom.xml中添加對(duì)service項(xiàng)目的依賴

<dependencies>

? ? <dependency>

? ? ? ? <artifactId>service</artifactId>

? ? ? ? <groupId>com.bjsxt</groupId>

? ? ? ? <version>1.0-SNAPSHOT</version>

????</dependency>

</dependencies>

9.創(chuàng)建接口和實(shí)現(xiàn)類

創(chuàng)建com.bjsxt.service.ConsumerService接口

創(chuàng)建com.bjsxt.servioce.impl.ConsumerServiceImpl實(shí)現(xiàn)類

public interface ConsumerService{

? ? String consumerService(String param);

}

@Service

public class ConsumerServiceImpl implements ConsumerService{

? ? @Override

? ? public String consumerService(String param){

? ? ? ? try{

? ? ? ? ? ? Zookeeper zookeeper = new Zookeeper("192.168.232.132:2181",60000,new Watcher(){

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public void process(WatchedEvent watchedEvent){

? ? ? ? ? ? ? ? ? ? System.out.println("獲取連接");

????????????????}

????????????});

? ? ? ? ? ? byte[] urlByte = zookeeper.getData("/demo/demoService",false,null);

? ? ? ? ? ? DemoService demoService = (DemoService)Naming.lookup(new String(urlByte));

? ? ? ? ? ? String result = demoService.demo(param);

? ? ? ? ? ? System.out.println(result);

? ? ? ? ? ? return result;

????????}catch(IOException e){

? ? ? ? ? ? e.printStackTrace();

????????}catch(InteruptedException e){

? ? ? ? ? ? e.printlnStackTrace();

????????}catch(NotBoundException e){

? ? ? ? ? ? e.printStackTrace();

????????}

? ? ? ? return null;

? ? }

}

10.創(chuàng)建控制器

創(chuàng)建com.bjsxt.controller.DemoController控制器

@Controller

public class DemoController{

? ? @Autowired

? ? private ConsumerService consumerService;

? ? @RequestMapping("/demo")

? ? @ResponseBody

? ? public String demo(String param){

? ? ? ? return consumerService.consumerService(param);

????}

}

11.創(chuàng)建啟動(dòng)器

創(chuàng)建com.bjsxt.ConsumerApplication

@SpringBootApplication

public class ConsumerApplication{

? ? public static void main(String[] args){

? ? ? ? SpringApplication.run(ConsumerApplication.class,args);

????}

}

12.測(cè)試

在瀏覽器輸入:http://localhost:8080/demo?param=demo

觀察結(jié)果是否是:demo123

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末浮驳,一起剝皮案震驚了整個(gè)濱河市疤苹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梯浪,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贯被,死亡現(xiàn)場(chǎng)離奇詭異媚朦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)啰脚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)实夹,“玉大人橄浓,你說(shuō)我怎么就攤上這事∈詹粒” “怎么了贮配?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)塞赂。 經(jīng)常有香客問(wèn)我泪勒,道長(zhǎng),這世上最難降的妖魔是什么宴猾? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任圆存,我火速辦了婚禮,結(jié)果婚禮上仇哆,老公的妹妹穿的比我還像新娘沦辙。我一直安慰自己,他們只是感情好讹剔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布油讯。 她就那樣靜靜地躺著,像睡著了一般延欠。 火紅的嫁衣襯著肌膚如雪陌兑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天由捎,我揣著相機(jī)與錄音兔综,去河邊找鬼。 笑死狞玛,一個(gè)胖子當(dāng)著我的面吹牛软驰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播心肪,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锭亏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蒙畴?” 一聲冷哼從身側(cè)響起贰镣,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤呜象,失蹤者是張志新(化名)和其女友劉穎膳凝,沒(méi)想到半個(gè)月后碑隆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹬音,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年上煤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片著淆。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡劫狠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出永部,到底是詐尸還是另有隱情独泞,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布苔埋,位于F島的核電站懦砂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏组橄。R本人自食惡果不足惜荞膘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望玉工。 院中可真熱鬧羽资,春花似錦、人聲如沸遵班。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)狭郑。三九已至腹暖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愿阐,已是汗流浹背微服。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缨历,地道東北人以蕴。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像辛孵,于是被迫代替她去往敵國(guó)和親丛肮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350