转载自郭无心的文章,帮助了我的项目开发
链接:https://www.zhihu.com/question/40752932/answer/88067718
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
memcached的客户端jar包我知道的有两个
alisoft-xplatform-asf-cache-2.5.1.jar -------- alisoft-xplatform-asf-cache是阿里的架构师岑文初进行封装的,用作memcache的访问和操作,里面的注释都是中文的。
memcached-2.5.jar
Memcached的客户端API包,官方出品。
-----------------------------------------------------------------------------------------
我所知道的memcached的mysql缓存封装方式,简单来看就是先通过sql语句通过网络进行访问,取到数据之后存放到memcached当中去,然后当需要使用数据的时候,首先从memcached当中获取,当获取不到再从mysql当中获取。
在数据量和访问量不大的情况下,使用memcached的必要性不大,因为memcached吃内存很厉害,所以开单机的memcached不划算,还不如将数据直接用map存放到内存中去,游戏服务器一般都是这么做的,服务器启动初始化过程中就将游戏静态配置数据加载到内存中去,然后直接在需要的时候访问内存就可以了。
----------------------------------------------------------------------------------------------在大型web应用中,每张表都很大,所以读取压力很大,因此设计分布式的memcached十分有必要。
-----------------------------------------------------------------------------------------------
提供一个简单示例,通过memcached来缓存数据。
<img src="https://pic1.zhimg.com/50/caa7d59647b9c730bc3e7e5642c4a03e_hd.jpg" data-rawwidth="336" data-rawheight="327" class="content_image" width="336">

package bean;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = -3896605600471191953L;
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password="
+ password + "]";
}
}
package memcachedTest;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;
import util.UserDao;
import bean.User;
import com.alisoft.xplatform.asf.cache.memcached.client.MemCachedClient;
import com.alisoft.xplatform.asf.cache.memcached.client.SockIOPool;
public class MemcachedManager {
// 创建MemCachedClient全局对象
private static MemCachedClient mcc = new MemCachedClient();
static {
// 创建服务器列表及其权重
String[] servers = { "127.0.0.1:11211" };
Integer[] weights = { 3 };
// 创建Socket连接池对象
SockIOPool pool = SockIOPool.getInstance();
// 设置服务器信息
pool.setServers(servers);
pool.setWeights(weights);
pool.setFailover(true);
// 设置初始连接数、最小和最大连接数以及最大处理时间
pool.setInitConn(5);
pool.setMinConn(5);
pool.setMaxConn(250);
pool.setMaxIdle(1000 * 60 * 60 * 6);
// 设置主线程睡眠时间
pool.setMaintSleep(30);
// 设置TCP参数、连接超时等
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setSocketConnectTO(0);
pool.setAliveCheck(true);
// 初始化连接池
pool.initialize();
// 压缩设置,超过指定大小(单位为K)的数据都会被压缩
mcc.setCompressEnable(true);
mcc.setCompressThreshold(64 * 1024);
}
/**
* 无参构造
*/
protected MemcachedManager() {
}
// 受保护的对象
protected static MemcachedManager instance = new MemcachedManager();
/**
* 为受保护的对象提供一个公共的访问方法
*/
public static MemcachedManager getInstance() {
return instance;
}
/**
* 添加对象到缓存中,构成方法重载
*
* @param key
* @param value
* @return
*/
public boolean add(String key, Object value) {
return mcc.add(key, value);
}
public boolean add(String key, Object value, Date expiry) {
return mcc.add(key, value, expiry);
}
public boolean replace(String key, Object value) {
return mcc.replace(key, value);
}
public boolean replace(String key, Object value, Date expiry) {
return mcc.replace(key, value, expiry);
}
/**
* 根据指定的关键字获取对象
*/
public Object get(String key) {
return mcc.get(key);
}
/**
* 利用MemCached对象将集合存入缓存,并从缓存中取出
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
* @throws InterruptedException
*/
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException, InterruptedException {
// 得到MemcachedManager实例
final MemcachedManager cache = MemcachedManager.getInstance();
// 创建UserDao对象
final UserDao userDao = new UserDao();
// 得到集合对象
final List<User> userList = userDao.getUserList();
System.out.println("从数据库当中取出数据" + userList);
// 创建User对象
User user = null;
for (int i=0; i<userList.size(); i++)
{
// 循环遍历集合对象
user = (User)userList.get(i);
// 将集合对象存入缓存中
cache.add(String.valueOf(user.getId()),user.getUsername());
// 将集合从缓存中取出
String uname = (String)cache.get(String.valueOf(user.getId()));
System.out.println("从缓存中取得的集合为:" + uname);
}
//下面尝试获取id用户
User user2 = userDao.getUserById(3,cache);
System.out.println(user2);
}
}
package util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcConnector {
// 定义数据库连接常量
private final static String DRIVER = "com.mysql.jdbc.Driver";
private final static String URL = "jdbc:mysql://127.0.0.1:3306/guowuxin";
private final static String DBNAME = "root";
private final static String DBPASS = "admin";
/**
* 得到数据库连接
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
public Connection getConn()throws ClassNotFoundException,SQLException {
// 加载驱动
Class.forName(DRIVER);
// 通过DriverManager对象得到连接
Connection conn = DriverManager.getConnection(URL,DBNAME,DBPASS);
// 返回数据库连接
return conn;
}
}
package util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import memcachedTest.MemcachedManager;
import bean.User;
public class UserDao extends JdbcConnector {
// 定义全局变量
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
/**
* 根据Id查询用户
*
* @param uid
* @return
*/
public User getUserById(int uid,MemcachedManager cache) {
// 创建User对象
User user = null;
if(cache.get(String.valueOf(uid)) != null)
{
user = new User();
user.setUsername((String)cache.get(String.valueOf(uid)));
System.out.println("从Cache中命中用户" + uid);
return user;
}
// 创建SQL语句
String sql = "select * from user where id=?";
try {
// 获得数据库连接
conn = this.getConn();
// 通过Connection对象创建PrepareStatement对象
pstmt = conn.prepareStatement(sql);
// 设置SQL语句的参数
pstmt.setInt(1, uid);
// 执行查询,将查询结果赋给ResultSet对象
rs = (ResultSet) pstmt.executeQuery();
// 遍历指针
while (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
/**
* 查询所有用户
*/
public List<User> getUserList() {
// 创建ArrayList对象
List<User> userList = new ArrayList<User>();
// 创建SQL对象
String sql = "select * from user";
try {
conn = this.getConn();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
userList.add(user);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return userList;
}
}
package util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Md5 {
private static final char[] HEX_TABLE = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static String md5(final String source)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(source.getBytes("utf-8"));
final byte[] bytes = messageDigest.digest();
return byteToHexString(bytes);
}
private static String byteToHexString(final byte[] bytes) {
return byteToHexString(bytes, 0, bytes.length - 1);
}
private static String byteToHexString(final byte[] bytes, final int begin,
final int end) {
if (bytes == null) {
return null;
}
final int length = bytes.length;
if (begin < 0 || begin > end || end > length) {
return null;
}
final StringBuilder builder = new StringBuilder();
for (int i = begin; i <= end; i++) {
final byte data = bytes[i];
builder.append(HEX_TABLE[data & 0xFF >>> 4]);
builder.append(HEX_TABLE[data & 0x0F]);
}
return builder.toString();
}
}