每天資訊Java編碼利器Guava,用起來吧

菜單

Java編碼利器Guava,用起來吧

Guava

Google出品,必屬精品。類似於

Apache Commons

,Guava這個庫是為了方便編碼,並減少編碼錯誤。它提供了集合,反射,快取,科學計算,xml,io等一些工具類庫。特點如下:

高效 - 可靠,良好的API,被Google的開發者設計,實現和使用。

函數語言程式設計 -增加JAVA功能和處理能力。

遵循高效的java語法實踐。

使程式碼更刻度,簡潔,簡單。

節約時間,資源,提高生產力。

Guava包括了谷歌很多的核心庫,極大的方便程式開發。相信有很多的人都用過,像集合、字串、io等工具類。

這篇文章主要帶大家瞭解下Guava高階知識,快取和併發。

Guava Cache

說到快取,通常會想到快取資料庫就是Redis和Mongo,這兩款K-V資料庫極其適合在微服務架構下做快取使用,速度也極高。但是怎麼說呢,還是沒有本地快吧,因為我們本地快取讀寫都是沒有網路I/O的,相當於一個Map結合。

Java編碼利器Guava,用起來吧

有疑問了,為啥我不直接用Map做快取就行了,如果資料量小的情況下,我想還是很適合的。但是資料量很大的情況下就會把Map給撐爆,導致記憶體溢位,好解決,你去重啟服務就好了啊,崩了再重啟。

Guava Cache為我們解決了上述的問題。控制資料量的大小和生命週期,例子

// 透過CacheBuilder構建一個快取例項

Cache cache = CacheBuilder。newBuilder()

。maximumSize(100) // 設定快取的最大容量

。expireAfterWrite(30, TimeUnit。MINUTES) // 設定快取30分鐘後失效

。concurrencyLevel(10) // 設定併發級別為10,(和cpu核數有關)

。recordStats() // 開啟快取統計

。build();

cache。put(“xxx”, “value”);

// 獲取快取

String value = cache。getIfPresent(“xxx”);

maximumSize

(),這個方法指定快取能儲存的最大容量,當快取數量達到這個值的時候,Guava 會先從快取的物件記錄中刪除一條來騰出新的空間,再put資料進去。

還有

maximumWeight

()方法也是設定最大容量的,只能設定一個。這個引數與

maximumSize

的區別就是當快取的最大數量/容量逼近或超過我們所設定的最大值時,Guava就會使用LRU演算法對之前的快取進行回收。

expireAfterWrite

(),這個方法跟redis提供的expire差不多,指明快取寫入後有效時長。

Guava RateLimiter

Guava提供的限流工具類,限制併發和請求量,目的是為了聽過限速來保護系統,一旦達到限制速率則可以拒絕服務或進行流量整形。

先了解下限流常用的兩種演算法:漏桶演算法和令牌桶演算法。

一、漏桶演算法

Java編碼利器Guava,用起來吧

很明顯,不定時的向一個桶中流入水滴,桶以一定的速度流出水滴。桶的容量也就是最大併發量,如果滿了,那不好意思,我無視你的請求。漏桶可以看作是一個帶有常量服務時間的單伺服器佇列,如果漏桶(包快取)溢位,那麼資料包會被丟棄。

其實簡單來說就是,流入代表了請求,如果說流入的速度很快,流出速度較慢,那桶肯定過會就滿了,來達到限流效果。

二、令牌桶演算法

Java編碼利器Guava,用起來吧

按照固定速率往桶中新增令牌,每次請求的時候嘗試從桶中獲取令牌,沒有拿到就拒絕請求了。當然如果請求量過少的話也會導致桶溢位。

傳遞不同大小的資料包,消耗的令牌數量不一樣。不要以為都只是拿一個,這個和執行緒是另外一碼事。

RateLimiter是基於令牌桶的流控演算法,RateLimiter會按照一定的頻率往桶裡扔令牌,執行緒拿到令牌才能執行,它通常用於限制對一些物理資源或者邏輯資源的訪問速率。這個大家可能會想到訊號量(Semaphore),這個只是限制了併發訪問的數量,和速率無關。

基礎使用:

public static void main(String[] args) {

// 每秒只發出5個令牌

RateLimiter limiter = RateLimiter。create(5);

for (int i = 0; i < 10; i++) {

// 請求RateLimiter, 超過permits會被阻塞,然後等待獲取令牌

limiter。acquire();

System。out。println(“執行業務。。” + i);

}

}

以上所說的快取和限流僅僅只是針對單機服務的,而現在很多系統都是分散式架構了。如果是分散式的話,那肯定無能為力了,對於分散式系統而言,快取就會用Redis和Mongo了,限流的話可以採用redis的令牌桶演算法,阿里的Sentinel。

上面所說的兩個知識點只是Guava的冰山一角,還不能在分散式情況使用,但是它強大的集合、函數語言程式設計、EventBus、I/O等工具類會在專案中更實用,無論單機還是叢集。