下面是一套 完整、可直接运行 的 Java 连接 Memcached 示例,基于目前最主流、维护活跃的客户端:
推荐客户端:XMemcached(推荐生产使用)
官网:https://github.com/killme2008/xmemcached
优点:高性能、支持二进制协议、连接池、失败重试、权重、动态扩缩容、集成 Spring
1. 添加 Maven 依赖
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.8</version>
</dependency>
最新版本查看:Maven Central
2. 基础连接代码(单机)
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.utils.AddrUtil;
import java.util.concurrent.TimeoutException;
public class MemcachedDemo {
public static void main(String[] args) throws Exception {
// 1. 创建客户端构建器
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses("127.0.0.1:11211") // 支持多节点: "host1:11211,host2:11212"
);
// 可选配置
builder.setConnectionPoolSize(5); // 连接池大小
builder.setOpTimeout(1000); // 操作超时 1s
builder.setConnectTimeout(3000); // 连接超时 3s
builder.setFailureMode(true); // 节点故障时自动摘除
// 2. 构建客户端
MemcachedClient client = builder.build();
try {
// 3. 基本操作
client.set("name", 3600, "张三"); // 过期时间 1 小时
client.set("age", 0, 25); // 0 = 永不过期
// 获取
String name = client.get("name");
Integer age = client.get("age");
System.out.println("name = " + name + ", age = " + age);
// 自增
long counter = client.incr("counter", 1, 0);
System.out.println("counter = " + counter);
// 删除
client.delete("name");
} catch (TimeoutException e) {
System.err.println("操作超时: " + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 4. 关闭客户端(应用退出时)
client.shutdown();
}
}
}
集群连接(多节点 + 权重)
// 格式: server1:port1 weight1, server2:port2 weight2
List<InetSocketAddress> servers = AddrUtil.getAddresses("node1:11211 3, node2:11211 2, node3:11211 1");
MemcachedClientBuilder builder = new XMemcachedClientBuilder(servers);
builder.setConnectionPoolSize(10);
builder.setFailureMode(true); // 故障转移
MemcachedClient client = builder.build();
高级功能
| 功能 | 代码 |
|---|---|
| CAS 操作(乐观锁) | client.cas("key", value, getsResult) |
| 批量获取 | client.get(List<String> keys) |
| 批量设置 | client.setMulti(map) |
| Touch 延长 TTL | client.touch("key", 3600) |
| 统计信息 | client.getStats() |
| 动态添加节点 | client.addServer("newhost:11211") |
| 删除节点 | client.removeServer("oldhost:11211") |
CAS 示例(防止并发覆盖)
GetsResponse<String> gets = client.gets("counter");
long cas = gets.getCas();
String oldValue = gets.getValue();
if (client.cas("counter", 3600, "newValue", cas)) {
System.out.println("CAS 成功");
} else {
System.out.println("CAS 失败,已被他人修改");
}
Spring Boot 集成(推荐)
1. pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.8</version>
</dependency>
2. application.yml
memcached:
servers: 127.0.0.1:11211,192.168.1.10:11211
poolSize: 10
opTimeout: 1000
3. 配置类
@Configuration
@ConfigurationProperties(prefix = "memcached")
@Data
public class MemcachedConfig {
private String servers;
private int poolSize = 5;
private long opTimeout = 1000;
}
@Configuration
@EnableConfigurationProperties(MemcachedConfig.class)
public class XMemcachedAutoConfig {
@Bean
public MemcachedClient memcachedClient(MemcachedConfig config) throws IOException {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses(config.getServers())
);
builder.setConnectionPoolSize(config.getPoolSize());
builder.setOpTimeout(config.getOpTimeout());
builder.setFailureMode(true);
return builder.build();
}
}
4. 使用
@Service
@RequiredArgsConstructor
public class CacheService {
private final MemcachedClient client;
public void set(String key, Object value, int exp) throws Exception {
client.set(key, exp, value);
}
public <T> T get(String key) throws Exception {
return client.get(key);
}
}
其他客户端对比
| 客户端 | 协议 | 连接池 | 集群 | 维护状态 | 推荐 |
|---|---|---|---|---|---|
| XMemcached | 二进制/文本 | 是 | 权重、动态 | 活跃 | 5 stars |
| Spymemcached | 二进制 | 是 | 一致性哈希 | 已停止 | 3 stars |
| Memcached-Java-Client | 文本 | 否 | 否 | 停止 | 1 star |
结论:生产环境首选 XMemcached
连接测试工具
public static boolean testConnection(String host, int port) {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), 2000);
return true;
} catch (Exception e) {
return false;
}
}
常见错误与排查
| 错误 | 原因 | 解决 |
|---|---|---|
java.net.ConnectException | 端口不通 | telnet ip 11211 |
TimeoutException | 网络延迟/超时 | 调大 opTimeout |
Authentication failure | 启用 SASL | 配置用户名密码 |
ClassCastException | 序列化不一致 | 统一使用 Serializable 或 JSON |
启用 SASL 认证(安全模式)
builder.setAuthInfoMap(AddrUtil.getAddressMap("127.0.0.1:11211", "user:password"));
启动 Memcached:
memcached -S -u user -p password
最佳实践总结
| 项目 | 建议 |
|---|---|
| 客户端 | 使用 XMemcached |
| 连接池 | 至少 5~10 |
| 超时 | opTimeout=1000, connectTimeout=3000 |
| 序列化 | 优先 Serializable,复杂对象用 Jackson JSON |
| 异常处理 | 捕获 TimeoutException, MemcachedException |
| 关闭 | 应用退出时 client.shutdown() |
一键运行完整示例(含 JSON 序列化)
// 添加 Jackson 依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
// 使用
ObjectMapper mapper = new ObjectMapper();
User user = new User("李四", 30);
client.set("user:1", 3600, mapper.writeValueAsString(user));
String json = client.get("user:1");
User u = mapper.readValue(json, User.class);
需要我帮你生成:
- Spring Boot 完整项目模板?
- Docker + Memcached + Java 集成?
- 监控 + 健康检查?
- 分布式锁实现?
直接告诉我你的场景(单机/集群、Spring/非 Spring、是否认证),我给你 一键可运行代码!