SpringBoot整合Memcached

Memcached簡介

Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護進程通信。

爲了提高性能,memcached中保存的數據都存儲在memcached內置的內存存儲空間中。由於數據僅存在於內存中,因此重啓memcached、重啓操作系統會導致全部數據消失。另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)算法自動刪除不使用的緩存。memcached本身是爲緩存而設計的服務器,因此並沒有過多考慮數據的永久性問題。

Memcached安裝

我是參考這個安裝的:https://www.runoob.com/memcached/window-install-memcached.html

Java客戶端選型

根據閱讀這篇文章,最後選擇使用XMemcached,前兩個都已經停止更新了。

XMemcached介紹

是使用最爲廣泛的Memcache Java客戶端,是一個全新的 Java Memcache Client。Memcache 通過它自定義協議與客戶端交互,而XMemcached就是它的Java客戶端實現,相比較於其他客戶端來說XMemcached 的優點如下

XMemcached主要特性

XMemcached 支持設置連接池、宕機報警、使用二進制文件、一致性Hash、進行數據壓縮等操作,總結下來有以下一些點

  • 性能優勢,使用的NIO
  • 協議支持廣泛
  • 支持客戶端分佈,提供了一致性Hash 實現
  • 允許設置節點權重,XMemcached允許通過設置節點的權重來調節Memcached的負載,設置的權重越高,該Memcached節點存儲的數據就越多,所要承受的負載越大
  • 動態的增刪節點,Memcached允許通過JMX或者代碼編程來實現節點的動態的添加或者刪除操作。方便擴展或者替換節點。
  • XMemcached 通過 JMX 暴露的一些接口,支持Client本身的監控和調整,允許動態設置調優參數、查看統計數據、動態增刪節點等;
  • 支持鏈接池操作。
  • 可擴展性強,XMemcached是基於Java NIO框架 Yanf4j 來實現的,所以在結構上相對清晰,分層明確。

整合SpringBoot

依賴

Maven依賴:

<!--memcache-->
<!-- https://mvnrepository.com/artifact/com.googlecode.xmemcached/xmemcached -->
<dependency>
    <groupId>com.googlecode.xmemcached</groupId>
    <artifactId>xmemcached</artifactId>
    <version>2.4.5</version>
</dependency>

<!--使用註解處理器來生成自己的元數據:參考:https://www.jianshu.com/p/57fec884c017-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

配置

當然在添加配置文件的時候,SpringBoot默認沒有支持自動配置所以需要使用SpringBoot提供的配置文件機制來編寫自己的配置文件。

1、application.yml添加配置:

# ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ memcache 配置 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ #
spring:    
    memcache:
        # memcached服務器節點
        servers: 127.0.0.1:11211
        # nio連接池的數量
        poolSize: 10
        # 設置默認操作超時
        opTimeout: 3000
        # 是否啓用url encode機制
        sanitizeKeys: false

2、新建 XMemcachedProperties 類,用於保存yml中的配置

package com.blog.www.config.memcache;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

/**
 * XMemcached 配置屬性,讀取的是 yml 文件中 spring.memcached 開頭的屬性
 */
@ConfigurationProperties(prefix = "spring.memcached")
@PropertySource("classpath:application.yml")
@Configuration
@Data
public class XMemcachedProperties {

	/**
	 * memcached服務器節點
	 */
	private String servers;

	/**
	 * nio連接池的數量
	 */
	private Integer poolSize;

	/**
	 * 設置默認操作超時
	 */
	private Long opTimeout;

	/**
	 * 是否啓用url encode機制
	 */
	private Boolean sanitizeKeys;

}

3、新建 MemcachedConfig 初始化配置

package com.blog.www.config.memcache;

import lombok.extern.slf4j.Slf4j;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator;
import net.rubyeye.xmemcached.utils.AddrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

/**
 * Memcached 配置
 */
@Configuration
@Slf4j
public class MemcachedConfig {

	@Autowired
	private XMemcachedProperties xMemcachedProperties;

	@Bean
	public MemcachedClient getMemcachedClinet(){
		MemcachedClient memcachedClient = null;
		try {
			MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(xMemcachedProperties.getServers()));
			builder.setFailureMode(false);
			builder.setSanitizeKeys(xMemcachedProperties.getSanitizeKeys());
			builder.setConnectionPoolSize(xMemcachedProperties.getPoolSize());
			builder.setOpTimeout(xMemcachedProperties.getOpTimeout());
			builder.setSessionLocator(new KetamaMemcachedSessionLocator());
			builder.setCommandFactory(new BinaryCommandFactory());
			memcachedClient = builder.build();
		}catch (IOException e){
			log.error("init MemcachedClient failed:", e);
		}
		return memcachedClient;
	}

}

使用

package com.blog.www.base;

import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * 測試基類,其他類繼承此類
 * <br/>
 * @author     :leigq
 * @date       :2019/8/13 17:17
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public abstract class BaseApplicationTests {

    protected Logger log = LoggerFactory.getLogger(this.getClass());

    private Long time;

    @Before
    public void setUp() {
        this.time = System.currentTimeMillis();
        log.info("==> 測試開始執行 <==");
    }

    @After
    public void tearDown() {
        log.info("==> 測試執行完成,耗時:{} ms <==", System.currentTimeMillis() - this.time);
    }
}

package com.blog.www;

import com.blog.www.base.BaseApplicationTests;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.TimeoutException;

/**
 * Memcached 測試
 */
public class MemcachedTest extends BaseApplicationTests {

	@Autowired
	private MemcachedClient memcachedClient;

	@Test
	public void test() throws InterruptedException, TimeoutException, MemcachedException {
		// 放入緩存
		boolean flag = memcachedClient.set("a", 0,  1);

		// 取出緩存
		Object a = memcachedClient.get("a");
		log.warn("a is [{}]", a);

		// 3s後過期
		memcachedClient.set("b", 3, 2);
		Object b = memcachedClient.get("b");
		log.warn("b is [{}]", b);

		Thread.sleep(3000);
		b = memcachedClient.get("b");
		log.warn("b is [{}]", b);
	}

}

執行結果如下:

20191014213932.png

其它

  • 參考:https://blog.csdn.net/nihui123/article/details/101101222
  • xmemcached Github:https://github.com/killme2008/xmemcached
  • 深入使用XMemcached:http://www.imooc.com/article/256593
  • memcache及使用場景:https://blog.csdn.net/weixin_43101391/article/details/82937849
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章