Ⅰ java.nio.channels.closedchannelexception 是什麼原因,怎麼處理
Java7(即JDK1.7)裡面還是有java.nio.file.FileSystems的。題主用的JDK是什麼版本?
Ⅱ java微服務開發,為什麼只依賴了介面就能拿到實例
因為微服務之間要調用彼此的介面。
SpringCloud中服務之間的兩種調用RESTful介面通信的方式:RestTemplateFeignRestTemplate是一個Http客戶端,類似於HTTPClient,org但比HTTPClient更簡單。這種限制介面調用次數的方式,我們通常稱之為限流。
一個微服務的服務注冊中心,nacos關閉後服務的鏈接不會失效。
Ⅲ java分布式架構有哪些技術
既然是分布式系統,系統間通信的技術就不可避免的要掌握。
首先,我們必須掌握一些基本知識,例如網路通信協議(例如TCP / UDP等),網路IO(Blocking-IO,NonBlocking-IO,Asyn-IO),網卡(多隊列等)。 了解有關連接重用,序列化/反序列化,RPC,負載平衡等的信息。
在學習了這些基本知識之後,您基本上可以在分布式系統中編寫一個簡單的通信模塊,但這實際上還遠遠不夠。 現在,您已經進入了分布式欄位,您已經對規模有很多要求。 這意味著需要一種通信程序,該程序可以支持大量連接,高並發性和低資源消耗。
大量的連接通常會有兩種方式:
大量client連一個server
當前在NonBlocking-IO非常成熟的情況下,支持大量客戶端的伺服器並不難編寫,但是在大規模且通常是長連接的情況下,有一點需要特別注意 ,即伺服器掛起時不可能所有客戶端都在某個時間點啟動重新連接。 那基本上是一場災難。 我見過一些沒有經驗的類似案例。 客戶端規模擴大後,伺服器基本上會在重新啟動後立即刷新。 大量傳入連接中斷(當然,伺服器的積壓隊列首先應設置為稍大一些)。 可以使用的通常方法是在客戶端重新連接之前睡眠一段隨機的時間。 另外,重連間隔採用避讓演算法。
一個client連大量的server
有些場景也會出現需要連大量server的現象,在這種情況下,同樣要注意的也是不要並發同時去建所有的連接,而是在能力范圍內分批去建。
除了建連接外,另外還要注意的地方是並發發送請求也同樣,一定要做好限流,否則很容易會因為一些點慢導致內存爆掉。
這些問題在技術風險上得考慮進去,並在設計和代碼實現上體現,否則一旦隨著規模上去了,問題一時半會還真不太好解。
高並發這個點需要掌握CAS、常見的lock-free演算法、讀寫鎖、線程相關知識(例如線程交互、線程池)等,通信層面的高並發在NonBlocking-IO的情況下,最重要的是要注意在整體設計和代碼實現上盡量減少對io線程池的時間佔用。
低資源消耗這點的話NonBlocking-IO本身基本已經做到。
伸縮性
分布式系統基本上意味著規模不小。 對於此類系統,在設計時必須考慮可伸縮性。 在體系結構圖上繪制的任何點,如果請求量或數據量繼續增加,該怎麼辦? 通過添加機器來解決。 當然,此過程不需要考慮無限的情況。 如果您有經驗的建築師,從相對較小的規模到非常大型的范圍,那麼優勢顯然並不小,而且它們也將越來越稀缺。 。
橫向可擴展性(Scale Out)是指通過增加伺服器數量來提高群集的整體性能。 垂直可伸縮性(Scale Up)是指提高每台伺服器的性能以提高集群的整體性能。 縱向可擴展性的上限非常明顯,而分布式系統則強調水平可伸縮性。
分布式系統應用服務最好做成無狀態的
應用服務的狀態是指運行時程序因為處理服務請求而存在內存的數據。分布式應用服務最好是設計成無狀態。因為如果應用程序是有狀態的,那麼一旦伺服器宕機就會使得應用服務程序受影響而掛掉,那存在內存的數據也就丟失了,這顯然不是高可靠的服務。把應用服務設計成無狀態的,讓程序把需要保存的數據都保存在專門的存儲上(eg. 資料庫),這樣應用服務程序可以任意重啟而不丟失數據,方便分布式系統在伺服器宕機後恢復應用服務。
伸縮性的問題圍繞著以下兩種場景在解決:
無狀態場景
對於無狀態場景,要實現隨量增長而加機器支撐會比較簡單,這種情況下只用解決節點發現的問題,通常只要基於負載均衡就可以搞定,硬體或軟體方式都有;
無狀態場景通常會把很多狀態放在db,當量到一定階段後會需要引入服務化,去緩解對db連接數太多的情況。
有狀態場景
所謂狀態其實就是數據,通常採用Sharding來實現伸縮性,Sharding有多種的實現方式,常見的有這么一些:
2.1 規則Sharding
基於一定規則把狀態數據進行Sharding,例如分庫分表很多時候採用的就是這樣的,這種方式支持了伸縮性,但通常也帶來了很復雜的管理、狀態數據搬遷,甚至業務功能很難實現的問題,例如全局join,跨表事務等。
2.2 一致性Hash
一致性Hash方案會使得加機器代價更低一些,另外就是壓力可以更為均衡,例如分布式cache經常採用,和規則Sharding帶來的問題基本一樣。
2.3 Auto Sharding
Auto Sharding的好處是基本上不用管數據搬遷,而且隨著量上漲加機器就OK,但通常Auto Sharding的情況下對如何使用會有比較高的要求,而這個通常也就會造成一些限制,這種方案例如HBase。
2.4 Copy
Copy這種常見於讀遠多於寫的情況,實現起來又會有最終一致的方案和全局一致的方案,最終一致的多數可通過消息機制等,全局一致的例如zookeeper/etcd之類的,既要全局一致又要做到很高的寫支撐能力就很難實現了。
即使發展到今天,Sharding方式下的伸縮性問題仍然是很大的挑戰,非常不好做。
上面所寫的基本都還只是解決的方向,到細節點基本就很容易判斷是一個解決過多大規模場景問題的架構師,:)
穩定性
作為分布式系統,必須要考慮清楚整個系統中任何一個點掛掉應該怎麼處理(到了一定機器規模,每天掛掉一些機器很正常),同樣主要還是分成了無狀態和有狀態:
無狀態場景
對於無狀態場景,通常好辦,只用節點發現的機制上具備心跳等檢測機制就OK,經驗上來說無非就是純粹靠4層的檢測對業務不太夠,通常得做成7層的,當然,做成7層的就得處理好規模大了後的問題。
有狀態場景
對於有狀態場景,就比較麻煩了,對數據一致性要求不高的還OK,主備類型的方案基本也可以用,當然,主備方案要做的很好也非常不容易,有各種各樣的方案,對於主備方案又覺得不太爽的情況下,例如HBase這樣的,就意味著掛掉一台,另外一台接管的話是需要一定時間的,這個對可用性還是有一定影響的;
全局一致類型的場景中,如果一台掛了,就通常意味著得有選舉機制來決定其他機器哪台成為主,常見的例如基於paxos的實現。
可維護性
維護性是很容易被遺漏的部分,但對分布式系統來說其實是很重要的部分,例如整個系統環境應該怎麼搭建,部署,配套的維護工具、監控點、報警點、問題定位、問題處理策略等等。
Ⅳ 關於java學習,有什麼書籍或者教程推薦不啦
你好,如果想學習java,推薦自學。如果覺得自己沒有自製力,可以去報個培育班,那裡有人教,會更好點。至於書的話,有很多的,比如說java編程思想等等,要結合自己的實際需要來選擇,然後就是努力了。祝你學有所成!
Ⅳ Java的技術架構有哪些
服務分離
隨著系統的的上線,用戶量也會逐步上升,很明顯一台伺服器已經滿足不了系統的負載,這時候,我們就要在伺服器還沒有超載的時候,提前做好准備。
由於我們是單體架構,優化架構在短時間內是不現實的,增加機器是一個不錯的選擇。這時候,我們可能要把應用和資料庫服務單獨部署,如果有條件也可以把文件伺服器單獨部署。
反向代理
為了提升服務處理能力,我們在Tomcat容器前加一個代理伺服器,我一般使用Nginx,當然你如果更熟悉apache也未嘗不可。
用戶的請求發送給反向代理,然後反向代理把請求轉發到後端的伺服器。
嚴格意義上來說,Nginx是屬於web伺服器,一般處理靜態html、css、js請求,而Tomcat屬於web容器,專門處理JSP請求,當然Tomcat也是支持html的,只是效果沒Nginx好而已。
反向代理的優勢,如下:
隱藏真實後端服務
負載均衡集群
高可用集群
緩存靜態內容實現動靜分離
安全限流
靜態文件壓縮
解決多個服務跨域問題
合並靜態請求(HTTP/2.0後已經被弱化)
防火牆
SSL以及http2
動靜分離
基於以上Nginx反向代理,我們還可以實現動靜分離,靜態請求如html、css、js等請求交給Nginx處理,動態請求分發給後端Tomcat處理。
Nginx 升級到1.9.5+可以開啟HTTP/2.0時代,加速網站訪問。
當然,如果公司不差錢,CDN也是一個不錯的選擇。
服務拆分
在這分布式微服務已經普遍流行的年代,其實我們沒必要踩過多的坑,就很容易進行拆分。市面上已經有相對比較成熟的技術,比如阿里開源的Dubbo(官方明確表示已經開始維護了),spring家族的spring cloud,當然具體如何去實施,無論是技術還是業務方面都要有很好的把控。
Dubbo
SpringCloud
服務發現——Netflix Eureka
客服端負載均衡——Netflix Ribbon
斷路器——Netflix Hystrix
服務網關——Netflix Zuul
分布式配置——Spring Cloud Config
微服務與輕量級通信
同步通信和非同步通信
遠程調用RPC
REST
消息隊列
持續集成部署
服務拆分以後,隨著而來的就是持續集成部署,你可能會用到以下工具。
Docker、Jenkins、Git、Maven
圖片源於網路,基本拓撲結構如下所示:
整個持續集成平台架構演進到如下圖所示:
服務集群
Linux集群主要分成三大類( 高可用集群, 負載均衡集群,科學計算集群)。其實,我們最常見的也是生產中最常接觸到的就是負載均衡集群。
負載均衡實現
DNS負載均衡,一般域名注冊商的dns伺服器不支持,但博主用的阿里雲解析已經支持
四層負載均衡(F5、LVS),工作在TCP協議下
七層負載均衡(Nginx、haproxy),工作在Http協議下
分布式session
大家都知道,服務一般分為有狀態和無狀態,而分布式sessoion就是針對有狀態的服務。
分布式Session的幾種實現方式
基於資料庫的Session共享
基於resin/tomcat web容器本身的session復制機制
基於oscache/Redis/memcached 進行 session 共享。
基於cookie 進行session共享
分布式Session的幾種管理方式
Session Replication 方式管理 (即session復制)
簡介:將一台機器上的Session數據廣播復制到集群中其餘機器上
使用場景:機器較少,網路流量較小
優點:實現簡單、配置較少、當網路中有機器Down掉時不影響用戶訪問
缺點:廣播式復制到其餘機器有一定廷時,帶來一定網路開銷
Session Sticky 方式管理
簡介:即粘性Session、當用戶訪問集群中某台機器後,強制指定後續所有請求均落到此機器上
使用場景:機器數適中、對穩定性要求不是非常苛刻
優點:實現簡單、配置方便、沒有額外網路開銷
缺點:網路中有機器Down掉時、用戶Session會丟失、容易造成單點故障
緩存集中式管理
簡介:將Session存入分布式緩存集群中的某台機器上,當用戶訪問不同節點時先從緩存中拿Session信息
使用場景:集群中機器數多、網路環境復雜
優點:可靠性好
缺點:實現復雜、穩定性依賴於緩存的穩定性、Session信息放入緩存時要有合理的策略寫入
Ⅵ 使用java發送簡訊驗證碼碼,出現流量限制怎麼辦急
簡訊驗證碼沒有什麼流量限制的,唯一可能的原因就是3點
1.簡訊介面欠費被限制了
2.你使用的個人手機號頻頻繁發簡訊會被運營商限制
3.你的介面被惡意請求,人家給你限制了
這些問題都只能找平台解決
Ⅶ Java的核心技術有哪些
第一:Java虛擬機 Java虛擬機的主要任務是裝在class文件並且執行其中的位元組碼。Java虛擬機包含一個類裝載器,它可以從程序和API中裝載class文件。Java API中只有程序執行時需要的那些類才會被裝載。位元組碼由執行引擎來執行。不同的Java虛擬機中,執行引擎可能實現得非常不同。在由軟體實現的虛擬機中,最簡單的執行引擎就是一次性解釋位元組碼。另一種執行引擎更快,但是也更消耗內存,叫做"即時編譯器(just-in-time compiler)"。在這種情況下,第一次被執行的位元組碼會被編譯成本地機器代碼。編譯出的本地機器代碼會被緩存,當方法以後被調用的時候可以重用。第三種執行引擎是自適應優化器。在這種方法里,虛擬機開始的時候解釋位元組碼,但是會監視運行中程序的活動,並且記錄下使用最頻繁的代碼段。程序運行的時候,虛擬機只把那些活動最頻繁的代碼編譯成本地代碼,其他的代碼由於使用得不是很頻繁,繼續保留為位元組碼-由虛擬機繼續解釋它們。一個自適應的優化器可以使得Java虛擬機在80%~90%的時間里執行被優化過的本地代碼,而只需要編譯10%~20%的對性能有影響的代碼。 當Java虛擬機是由主機操作系統上的軟體實現的時候,Java程序通過調用本地方法(native method)和主機交互。Java中有兩種方法: Java方法和本地方法。Java方法是由Java語言編寫,編譯成位元組碼文件,存儲在class文件中的。本地方法是由其他語言(比如c,c++或匯編語言)編寫的,編譯成何處理器相關的機器代碼。本地方法保存在動態鏈接庫中,格式是各個平台專有的。運行中Java程序調用本地方法時,虛擬機裝載包含這個本地方法的動態庫,並調用這個方法。本地方法是聯系Java程序和底層主機操作系統的連接方法。
第二:類裝載器的體系結構 一個Java應用程序可以使用兩種類裝載器:"啟動(bootstrap)"類裝載器和用戶定義的類裝載器。啟動類裝載器(這是系統中唯一的)是Java虛擬機實現的一部分。啟動類裝載器通常使用某種默認方式從本地磁碟中裝載類,包括Java API類(啟動類裝載器也被稱為原始類裝載器、系統類裝載器或者默認類裝載器)。 Java應用程序能夠在運行時安裝用戶定義的類裝載器,這種類裝載器能夠使用自定義的方式來裝載類。例如,從網路下載class文件。盡管啟動類裝載器是虛擬機實現的本質部分,而用戶定義的類裝載器不是,但用戶定義的類裝載器能夠用Java來編寫,能夠被編譯成class文件,能夠被虛擬機裝載,還能夠像其它對象一樣實例化。 由於有用戶定義類裝載器,所以不必再編譯的時候就知道運行中的Java應用程序中最終會加入的所有的類。用戶定義的類裝載器使得在運行擴展Java應用程序成為可能。當它運行時,應用程序能夠解決它需要哪些額外的類,能夠決定是使用一個或是更多的用戶定義的類裝載器來裝載。由於類裝載器是用Java編寫的,所以用任何在Java代碼中可以表述的風格來進行類裝載。這些類可以通過網路下載,可以從某些資料庫中獲取,甚至可以動態生成。 每一個類被裝載的時候,Java虛擬機都監視這個類,看到它到底是被啟動類裝載器還是被用戶定義類裝載器裝載。當被裝載的類引用了另外一個類時,虛擬機就會使用裝載第一個類的類裝載器裝載引用的類。例如,如果虛擬機使用一個特定的類裝載器裝載Volcano這個類,它就會使用這個類裝載器裝載Volcano類使用的所有類。 由於Java虛擬機採取這種方式進行類的裝載,所以被裝載的類默認情況下只能看到被同一個類裝載器裝載的別的類。通過這種方法,Java的體系結構允許在一個Java應用程序中建立多個命名空間。運行時的Java程序中的每一個類裝載器都有自己的命名空間。 Java應用程序可以創建多少個(或多少種)被不同的類裝載器裝載的類存放在不同的命名空間中,它們不能相互訪問,除非應用程序顯示地允許這么做。當編寫一個Java應用程序的時候,從不同源文件裝載的類可以分隔在不同的命名空間中。通過這種方法,就能夠使用Java類裝載器的體系結構來控制任何不同源文件中裝載的代碼之間的相互影響,特別是能夠阻止惡意代碼獲取訪問或破壞善意代碼的許可權。 Web瀏覽器是一個動態擴展的例子,Web瀏覽器使用用戶定義的類裝載器從網路下載用於Java applet的class文件。Web瀏覽器使用一個用來安裝用戶定義類裝載器的Java應用程序。這個用戶定義的類裝載器通常被稱為Java Applet類裝載器,它知道如何向HTTP伺服器請求class文件。Java Applet可以作為動態擴展的例子,因為Java應用程序並不知道它什麼時候會開始從網路下載瀏覽器請求的class文件。只有當瀏覽器遇到有Java applet的頁面時,才決定是否需要下載class文件。 Web瀏覽器啟動的Java應用程序通常為每個提供class文件的網路地址分別創建不同的用戶定義類裝載器,因此,不同的用戶定義類裝載器裝載不同來源的class文件。這就可以把它們分別放置在Java主機應用程序的不同命名空間之下。由於不同來源的Java applet文件放置在不同的命名空間中,惡意的Java applet代碼就不會直接訪問從別的地方下載的class文件。這就能夠限制或阻止不同來源的代碼之間的相互訪問。
第三:Java class文件 Java class文件主要在平台無關性和網路移動性方面使Java更適合網路。它在平台無關性方面的任務是:為Java程序提供獨立於底層主機平台的二進制形式的服務。這種途徑途徑打破了C或者C++等語言所遵循的傳統,使用這些傳統語言寫的程序通常首先被編譯,然後被連接成單獨的、專門支持特定硬體平台和操作系統的二進制文件。通常情況下,一個平台上的二進制可執行文件不能在其他平台上工作。而Java class文件時可以運行在任何支持Java虛擬機的硬體平台和操作系統上的二進制文件。 當編譯和連接一個C++程序時,所獲得的可執行二進制文件只能在指定的硬體平台和操作系統上運行,因為這個二進制文件包含了對目標處理器的機器語言。而Java編譯器把Java源文件的指令翻譯成位元組碼,這種位元組碼就是Java虛擬機的"機器語言"。class文件設計得緊湊,因此它們可以快速地在網路上傳送。其次,由於Java程序是動態連接和動態擴展的,class文件可以在需要的時候才下載。這個特點使得Java應用程序能夠安排從網路上下載class文件的時間,從而可以最大限度地減少終端用戶的等待時間。
第四:Java API Java API通過支持平台無關性和安全性,使得Java適應於網路應用。Java API是運行庫的集合,它提供了一套訪問主機系統資源的標准方法。運行Java程序時,虛擬機裝載程序的class文件所使用的Java API class文件。所有被裝載的class文件(包括從應用程序中和從Java API中提取的)和所有已經裝載的動態庫(包含本地方法)共同組成了再Java虛擬機上運行的整個程序。 在一個平台能偶支持Java程序以前,必須在這個特定平台上明確地實現API的功能。為訪問主機上的本地資源,Java API調用了本地方法。由於Java API class文件調用了本地方法,Java程序就不需要再調用它們了。通過這種方法,Java API class文件為底層主機提供了具有平台無關性、標准介面的Java程序。對Java程序而言,無論平台內部如何,Java API都會有同樣的表現和可預測的行為。正是由於在每個特定的主機平台上明確地實現了Java虛擬機和Java API,因此,Java程序自身就能夠成為具有平台無關性的程序。 Java API在Java安全性模型方面也有貢獻。當Java API的方法進行任何有潛在危險的操作(比如進行本地磁碟寫操作)之前,都會通過查詢訪問控制器來檢驗是否得到了授權。訪問控制器是一個類,該類用來執行棧檢驗,已決定是否允許某種操作。
Ⅷ java 如何保證釋放了io流
問題本質想問:不管是文件讀寫還是網路發送接收,信息的最小存儲單元都是位元組,那為什麼 I/O 流操作要分為位元組流操作和字元流操作呢?
回答:字元流是由 Java 虛擬機將位元組轉換得到的,問題就出在這個過程還算是非常耗時,並且,如果我們不知道編碼類型就很容易出現亂碼問題。所以, I/O 流就乾脆提供了一個直接操作字元的介面,方便我們平時對字元進行流操作。如果音頻文件、圖片等媒體文件用位元組流比較好,如果涉及到字元的話使用字元流比較好。
BIO,NIO,AIO 有什麼區別?
BIO (Blocking I/O): 同步阻塞 I/O 模式,數據的讀取寫入必須阻塞在一個線程內等待其完成。在活動連接數不是特別高(小於單機 1000)的情況下,這種模型是比較不錯的,可以讓每一個連接專注於自己的 I/O 並且編程模型簡單,也不用過多考慮系統的過載、限流等問題。線程池本身就是一個天然的漏斗,可以緩沖一些系統處理不了的連接或請求。但是,當面對十萬甚至百萬級連接的時候,傳統的 BIO 模型是無能為力的。因此,我們需要一種更高效的 I/O 處理模型來應對更高的並發量。