《SpringBoot2从入门到工程实战》第五篇:集成多实例Memcached

上一章我们介绍了多实例 Redis 的操作集成,本章,我们继续介绍缓存的另外一个集大成者——Memcached的使用。

作为现代互联网的基石软件之一,Memcached以其高性能、稳定性、易维护、使用简单、实现简单等诸多优点,现在仍然是大型业务系统的最重要数据存储软件之一,特别是在大型系统中,往往是几百个、几千个Memcached的实例对外提供访问来达到降低对MySQL的直接访问冲击。

在本章中我们介绍的是基于一致性Hash规则的Memcached集群的使用,如果你的业务是使用的Proxy代理模式,其实也是一样的。

本章示例工程名称:springboot_worker_multi_memcached

代码地址:https://github.com/stamhe/SpringBoot-Work-Example

目录结构如下:

pom.xml内容:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.stamhe</groupId>
  <artifactId>springboot_worker_multi_memcached</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springboot_worker_multi_memcached</name>
  <url>http://maven.apache.org</url>

  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
  </properties>
  
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

  <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- http://tengj.top/2017/04/05/springboot7/ -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-logging</artifactId>
	</dependency>
    
	<dependency>
		<groupId>net.spy</groupId>
		<artifactId>spymemcached</artifactId>
		<version>2.12.3</version>
	</dependency>
    
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

	<!-- 
	使用Spring Boot微服务搭建框架,在eclipse和Idea下能正常运行,但是在打成jar包部署或者直接使用java -jar命令的时候,
	提示了xxxxxx.jar中没有主清单属性.
	添加 spring-boot-maven-plugin然后再执行mvn install 或者 mvn clean package 即可解决.
	-->
	<build>
	  <plugins>
	  	<plugin>
	  		<groupId>org.springframework.boot</groupId>
	 		<artifactId>spring-boot-maven-plugin</artifactId>
	  	</plugin>
	  </plugins>
 	</build>
</project>

memcached的操作库,我们引入的是 spymemcached这个通用的依赖库。

App.java内容:

package com.stamhe.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;

@SpringBootApplication
@ComponentScan({"com.stamhe.springboot"})
@PropertySource({
	"classpath:/memcached.properties"
})
public class App 
{
    public static void main( String[] args )
    {
    	SpringApplication.run(App.class, args);
    }
}

引入了独立的 memcached.properties 配置文件。

MemcachedInit.java内容:

package com.stamhe.springboot.init;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import net.spy.memcached.MemcachedClient;

@Component
public class MemcachedInit implements CommandLineRunner {
	@Value("${springboot.memcached1.host}")
	String mhost1;
	
	@Value("${springboot.memcached1.port}")
	int mport1;

	@Value("${springboot.memcached2.host}")
	String mhost2;

	@Value("${springboot.memcached2.port}")
	int mport2;
	
	private MemcachedClient client;

	@Override
	public void run(String... args) throws Exception {
		try {
			// 一致性hash
			List<InetSocketAddress> list = new ArrayList<>();
			list.add(new InetSocketAddress(mhost1, mport1));
			list.add(new InetSocketAddress(mhost2, mport2));
			client = new MemcachedClient(list);
        } catch (Exception e) {
            System.out.println("inint MemcachedClient failed. error = " + e.getMessage());
        }
	}
	
	public MemcachedClient getClient() {
		return client;
	}
}

初始化Memcached连接参数,这儿使用了一致性hash。

HelloController.java内容:

package com.stamhe.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.stamhe.springboot.init.MemcachedInit;
import net.spy.memcached.MemcachedClient;

@RestController
@RequestMapping("/hello")
public class HelloController {
	@Autowired
	private MemcachedInit memcachedInit;

	@RequestMapping("/cache")
	public String cacheAction()
	{
		MemcachedClient cacheObj = memcachedInit.getClient();
		String key = "k1";
		// 过期时间单位: ms
		cacheObj.set(key, 60000, "v1");
		String value = cacheObj.get(key).toString();
		
		return value;
	}
}

操作Memcached的示例。

memcached.properties内容:

springboot.memcached1.host=127.0.0.1
springboot.memcached1.port=11211

springboot.memcached2.host=127.0.0.1
springboot.memcached2.port=11211

这儿为了方便,两个memcached实例都使用的相同的连接参数。

访问 http://localhost:8080/hello/cache 得到如下结果:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据