中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

web中遠程對象調用怎么理解

發布時間:2022-01-06 09:27:22 來源:億速云 閱讀:151 作者:iii 欄目:云計算

這篇文章主要講解了“web中遠程對象調用怎么理解”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“web中遠程對象調用怎么理解”吧!

要說“遠程對象”,必先說“遠程調用”,也就是RPC。比較著名的RPC框架有,最近很火的gRPC,也就是Google開源的RPC。另外還有Facebook開源的Thrift等等……我廠內部也有很多RPC框架,琳瑯滿目不暇接。Java在JDK里面也支持RMI(Remote Method Invoke: 遠程方法請求)功能,也可以視為一種RPC,但實際上這個更像我們現在要討論的“遠程對象調用”。

在諸多的RPC中,我們都基本認為是通過網絡,對運行在另外一個進程(或者電腦)里的某個函數,發起一次調用請求。既然是一次函數調用,那么我們自然要傳入參數,然后期望獲得返回值。在這個過程中,我們往往只需要輸入:函數名+參數,RPC就能找到一個遠程的進程,去執行對應的函數,然后傳入目標參數。在這個過程里,執行這個函數的進程,會被認為是無狀態的,所有的輸出,都僅與輸入的參數有關,除非有一部分狀態是記錄在數據庫(持久化設備)上的。因此,計算的過程(算法),和計算的數據,實際上分離的,這些計算所需的數據,要么來源于參數,要么是數據庫設備。而被請求的函數,以及裝載這個函數的容器——進程,是不保證任何的狀態維護能力的。

而“遠程對象調用”,正是在“狀態”這個環節上,和RPC不同——它是由框架去保證某種狀態的。當我們發起一個遠程對象調用的時候,是需要首先“找到”一個遠程對象,然后再發起“方法”(成員函數)調用。這和RPC就產生了兩個明顯的區別:

  1. 我們需要用某種手段定位到對象,而不是僅僅用一個函數名。對象是一個更復雜的遠程概念,因為有可能同屬于一個類(class),而存在多個狀態一致或不一致的對象,在遠程的機器上存在。我們就不能僅僅通過一個固定的路由標志(比如類名)去找一個這樣的對象。遠程對象的路由方式成為不同“遠程對象調用”框架之間的一個顯著區別。

  2. 我們并不需要把所有的數據,在每次請求時都通過參數發給遠程對象,因為對于同一個遠程對象來說,它是可以包含大量過程狀態的。我們只要找到正確的遠程對象,就能獲得之前操作所造成的結果狀態。有遠程對象往往是生存在進程的內存中,所以對于訪問自己的狀態數據,會非常快速,這對于有延遲壓力的程序來說,是非常有用的。

    web中遠程對象調用怎么理解

所以,遠程對象調用,最大的特點,就是數據和計算是合并在一起的——這很好的提高了使用面向對象編程的便利性,也大大降低了遠程調用中因為數據拉取產生的延遲。

遠程對象的優點:DB壓力、易用性

在傳統的“請求-響應”為基礎的分布式服務器中,最常見的數據系統是:接入-邏輯-緩存-數據庫 這樣一個四層結構。為了讓承擔計算壓力的“邏輯”模塊能分布到不同的進程上,我們往往會把“邏輯”模塊做成“無狀態”的,這樣我們就可以隨意的啟動、停止任何一個邏輯模塊的進程,而不需要擔心因此丟失用戶數據。但是這樣做,邏輯模塊是輕松了,承擔狀態存儲的“緩存-數據庫”哥倆壓力就大了。因為每一個數據操作,都需要去從他們這里讀取數據,然后再回寫結果(如果有數據修改操作的話)。
web中遠程對象調用怎么理解

一個客戶端程序,想要訪問一個EJB對象,一般需要使用一個叫做JNDI的API,來具體連接到EJB對象上。JNDI的全稱是Java Naming and Directory Inerface,基本等于我們常說的名字、目錄服務接口。Java通過一套API規范,來統一各種目錄服務器的使用方法。所有的J2EE容器,都必須提供一個JNDI服務,而客戶端程序則通過使用J2EE容器提供的JNDI來訪問容器內的EJB對象。JNDI的使用方法,基本上就是輸入一個字符串,然后API會返回給你一個對象。在J2EE的環境里,這個對象就是EJB對象的Home接口對象(對應遠程EJB對象的一個映像,也叫樁對象)。代碼類似:

Context ctx = new InitialContext(env);
Object ejbHome = ctx.lookup(“java:comp/env/ejb/HelloBean”);
HelloHome empHome = (HelloHome) PortableRemoteObject.narrow (ejbHome,  HelloHome.class);

輸入lookup()函數的字符串,是用戶可以自己定義的任何內容,只要在對應的EJB容器里面登記了這個對應關系即可。從這個代碼我們可以看到,如果EJB想要做容災、負載均衡等功能,是完全可以通過ctx.lookup()這個接口來實現的。另外,遠程對象的Home接口(樁代碼)是需要預先部署在客戶端測,在上面的例子里是HelloHome.class這個類。而EJB對象的這個Home接口類,是由EJB工具,自動通過來源的EJB對象類定義生成的。對比CORBA,Thrift等技術,EJB可以直接用.java源代碼代替IDL定義,然后自動生成樁代碼,這確實是簡便很多。

EJB規范把遠程對象定義為三種:無狀態會話Bean,有狀態會話Bean,消息驅動Bean。這意味著EJB容器對于EJB對象的生命周期是有管理的。其中無狀態會話Bean和消息驅動Bean的聲明周期是類似的,都是來一個請求(消息驅動的意思是每來一個JMS消息),就可能new一個Bean對象。當然也可能不是每次請求都新建對象,總之容器不保證會保持Bean對象的生存周期,這樣容器可以根據負載壓力,靈活的管理眾多的Bean對象。而最特別的是“有狀態會話Bean”,容器會根據客戶端的會話狀態(和客戶端的context對象對應),來保持Bean對象,也就是說,每個客戶端context對應一個有狀態Bean。如果你用這個客戶端context,發起多次lookup()查找,訪問的那個EJB對象都將會是同一個。這對于需要保持登錄狀態的服務,就非常方便了。客戶無需自己去維持一個遠程對象的生命周期,而能得到狀態保存的功能。

最后說說EJB的部署配置,以前的EJB容器部署異常復雜。除了需要寫一個繼承于特定基類的業務JAVA類外,還要配置很多細節。而EJB3.0之后,通過JAVA注解功能(Annotation),這些配置都可以和源代碼寫到一起,而業務JAVA類也無需集成特定的接口和類型,可以是任何一個普通的類(POJO),只是需要加上一些特定的注釋即可。EJB容器提供工具對這些加了EJB注釋的JAVA類進行處理,一方面把這個JAVA類自動部署到容器中,另一方面生成客戶端的Home接口類文件,供用戶發布(拷貝)到需要使用的客戶方服務器上去。而一些EJB容器(如Weblogic)還提供了Eclipse(IDE)的圖形界面工具,讓整個過程幾乎都不在需要編寫額外的配置和命令行操作。

2.MS WCF

WCF全稱Windows Communication Foundation,是微軟發布的用于構建面向服務的應用程序框架。這套框架的底層是Windows的COM+技術,而編程接口則更多的使用C#語言/VB語言和.Net平臺。這和EJB有一定的類似,差別就是WCF中的遠程對象,不需要一個像JVM那樣的虛擬機,而是結合在WINDOWS操作系統里。

無獨有偶,WCF的遠程接口定義,也是直接使用C#/VB代碼,加上類似注解的“特性”(Attribute)功能注釋,標注在一個定義好的接口(Interface)上來組成的。具體的業務實現類,只要“實現”定義的這個接口就可以了,和一個普通的類沒有任何差別。和EJB的差別是,我們還是需要寫一段XML配置,把這個遠程對象的接口和查找字符串,注冊到萬能的IIS服務器里面。一旦注冊完成,就可以通過URL:http://xx.xx.xx.xx/servicesname/service.svc這樣的字符串去訪問了。同時,如果客戶端想要訪問這個遠程對象,則需要使用svcuitl.exe這個工具,輸入剛剛注冊的那個URL,就可以生成對應的客戶端樁代碼庫。客戶端可以直接new這個新建立的樁類型對象,然后直接調用其方法,就和調用本地對象的方法一樣。

// Create a client.
CalculatorClient client = new CalculatorClient();

// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

當然,如果你想連接不同的服務器,還是有機會的,一位內生成的客戶端代碼,會使用一個配置文件。在里面可以修改遠程服務器的地址(還是那個注冊的URL)。

<client>
     <endpoint
         address="http://localhost/servicemodelsamples/service.svc" 
         binding="wsHttpBinding" 
         contract=" Microsoft.ServiceModel.Samples.ICalculator" />
</client>

你除了可以通過IIS來提供WCF的遠程對象服務外,還可以自己寫一個單獨的程序,通過定義main()來完全的控制這些遠程對象,從而提供服務。另外,WCF除了通過URL直接對應一個遠程對象外,還可以通過編寫“路由服務”,來對同一個URL的遠程對象調用進行靈活的路由。雖然WCF沒有提供類似EJB的遠程對象生命周期管理功能,但是你完全可以通過WCF的服務API和路由服務,來自己編碼實現任何形式的遠程對象生命周期管理。

3.IBM RMI-IIOP

IBM公司的RMI-IIOP服務,是以JAVA技術為基礎的,但是又不同于EJB的另外一套遠程對象技術。這套技術更接近于以JAVA為基礎實現的CORBA體系。這個技術的使用標準的JAVA RMI接口(RMIInterface)作為遠程對象的接口,使用JAVA的序列化、反序列化能力作為編碼能力。然后自己寫一個main()函數,建立一個org.omg.CORBA.ORB對象來構造一個遠程服務器。而客戶端則是通過一個字符串來定位想要訪問的遠程對象。這個字符串類似:corbaloc:iiop:1.2@localhost:8080/OurLittleClient 。我們可以看到這里面有IP和端口,還有一個編寫服務器遠程對象時注冊的字符串OurlLittleClient。我們通過rmic –iiop Server這樣的命令行部署遠程對象,然后用start java Server啟動服務器,用start java Client啟動客戶機。這些命名,都是包含在IBM Developer Kit for Java technology v1.3.1里面的。我們可以發現,RMI-IIOP是一個更加原始的遠程對象方案,基本上就是一個CORBA的API實現的組合。使用起來有點繁瑣,但是好處是不需要學習和部署復雜的容器服務,可以完全自己編碼去實現一套遠程對象服務。這里沒有限定你使用什么方法去定位查找遠程對象,也沒有限定你怎么管理遠程對象的生命周期,一切都由開發者自己去編寫實現。

小結
規范遠程對象定位遠程對象生命周期管理服務器部署
EJBJNDI路徑字符串查找自動管理,帶會話狀態對象使用容器服務
WCFURL、路由服務部署到IIS或自寫main()
RMI-IIOPCOBRA URL定位自寫main()

在對象定位的選擇上,通過字符串查找已經是標準,而復雜的自定義路由也可以隱藏在這個查找操作下面。遠程對象的生命周期管理,實際上是對服務器資源的管理,除了EJB有容器支持以外,其他的方案都比較少提供這樣的能力,說明這一塊是比較困難的。服務器部署方面,可以讓用戶以API自己寫main()去構建服務器,提供了極大的靈活性。

遠程對象的挑戰:生命周期管理、數據一致性

通過上面的分析,我們可以發現,遠程對象的生命周期管理,是一個比較重大且復雜的課題。我們要保證這樣的生命周期管理程序,能有一個通用的策略,來保持各種業務情況下的服務器資源穩定,是比較困難的。而且在分布式系統的情況下,為了負載均衡,還要把同樣類型的遠程對象,部署到不同的進程上,這就引入了一個新的問題:數據一致性。

遠程對象的生命周期,除了占用服務器的內存資源外,還會占用記錄其地址的路由空間,檢查維護生命周期的CPU運算時間。如果我們提供自動化的對象生命周期管理,勢必就需要在客戶使用的時候,提供這方面的教育,以及防止客戶使用錯誤、過載等情況下對象管理失效的防御性策略。所以即便是EJB容器,也僅僅提供了非常簡單的生命周期管理策略:會話狀態、無狀態這兩種。

對于一般的互聯網應用,只有EJB這兩種生命周期管理的遠程對象,基本上是夠用的。因為一般的互聯網應用,大部分數據都是持久化數據,需要讀寫數據庫。臨時狀態數據一般來說不多,主要是用戶登錄后的產生的一些過程數據,有一個“會話(Session)”類型的生命周期就足夠了。但是,如果我們的業務是網絡游戲,那么這么簡單的生命周期就是完全不夠的,因為游戲中有大量的臨時狀態,比如組隊的狀態,玩家所在房間的狀態,關卡副本的狀態等等。這些臨時狀態,都是需要我們通過業務邏輯代碼,來控制和管理所對應的對象生命周期的。所以一個適合游戲的遠程對象系統,需要提供讓客戶端程序來選擇,“新建/初始化”和“銷毀”遠程對象的能力。

在對遠程對象進行管理的時候,我們常常會用到一種叫“對象池”的技術,使用這種技術避免頻繁的新建和銷毀對象。但是如果這些對象的是帶狀態的,那么我們的“池”就必須帶索引,并且對象也必須有一個key。同時我們的對象還需要有一個“reset”的重置方法,用來讓對象回歸到初始化狀態。

在分布式的系統下,我們的對象池因為是分別存放在不同的機器上,所以其一致性的維護往往是比較困難的。但是,我們可以把這個問題,轉換成構建一個“分布式對象池”的問題。假如每個對象池,都按KEY的某個規律,如一致性哈希,存放不同的對象。那么只要在遠程調用發起的時候,也就是通過lookup()查找遠程對象的時候,把請求導向到對象所在進程,那么就能很方便的從本地進程對象池中獲得對象。遠程對象的“定位”和“一致性”在查找對象這個環節結合起來,是一個非常好的想法。這樣能讓遠程狀態對象的使用進一步簡化,用戶完全無需關心遠程對象在什么地方,又能快速的訪問到正確的對象。
web中遠程對象調用怎么理解
[擴容下的遠程對象遷移]

當分布式的對象容器出現部分進程故障,或者需要動態擴容的時候,只要我們針對對象查找的數據做某種程度的數據搬遷,或者緩存清理,就能很容易的實現對象的重新分布。如果對象同時能夠支持持久化,那么這種數據搬遷,只需要簡單的讓對象寫入持久化。然后在新的機器上,通過緩存建立的策略,從持久化設備讀取出對象即可。

感謝各位的閱讀,以上就是“web中遠程對象調用怎么理解”的內容了,經過本文的學習后,相信大家對web中遠程對象調用怎么理解這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

web
AI

澄城县| 运城市| 家居| 视频| 临猗县| 库车县| 昭通市| 理塘县| 高台县| 鲁甸县| 罗源县| 肇庆市| 永善县| 龙州县| 宁都县| 祥云县| 曲沃县| 北流市| 中宁县| 四平市| 阳信县| 武鸣县| 沂南县| 阜阳市| 通化县| 泗阳县| 焉耆| 财经| 沅江市| 库伦旗| 油尖旺区| 乌兰县| 天长市| 西城区| 瑞丽市| 旬邑县| 公主岭市| 无极县| 华容县| 宝鸡市| 陵川县|