diff --git a/cim-forward-route/src/main/java/com/crossoverjie/cim/route/config/BeanConfig.java b/cim-forward-route/src/main/java/com/crossoverjie/cim/route/config/BeanConfig.java index 34329c2a..d43ba8ea 100644 --- a/cim-forward-route/src/main/java/com/crossoverjie/cim/route/config/BeanConfig.java +++ b/cim-forward-route/src/main/java/com/crossoverjie/cim/route/config/BeanConfig.java @@ -4,12 +4,14 @@ import com.crossoverjie.cim.common.metastore.MetaStore; import com.crossoverjie.cim.common.metastore.ZkConfiguration; import com.crossoverjie.cim.common.metastore.ZkMetaStoreImpl; +import com.crossoverjie.cim.common.pojo.CIMUserInfo; import com.crossoverjie.cim.common.route.algorithm.RouteHandle; import com.crossoverjie.cim.common.route.algorithm.consistenthash.AbstractConsistentHash; import com.crossoverjie.cim.server.api.ServerApi; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.common.cache.Weigher; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import okhttp3.OkHttpClient; @@ -24,8 +26,12 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import java.lang.reflect.Method; +import java.time.Duration; +import java.util.Optional; import java.util.concurrent.TimeUnit; +import static com.crossoverjie.cim.route.constant.Constant.ACCOUNT_PREFIX; + /** * Function: * @@ -109,6 +115,26 @@ public RouteHandle buildRouteHandle() throws Exception { } + @Bean("userInfoCache") + public LoadingCache> userInfoCache(RedisTemplate redisTemplate) { + return CacheBuilder.newBuilder() + .initialCapacity(64) + .maximumSize(1024) + .concurrencyLevel(Runtime.getRuntime().availableProcessors()) + .expireAfterWrite(10, TimeUnit.MINUTES) + .build(new CacheLoader<>() { + @Override + public Optional load(Long userId) throws Exception { + String sendUserName = redisTemplate.opsForValue().get(ACCOUNT_PREFIX + userId); + if (sendUserName == null) { + return Optional.empty(); + } + CIMUserInfo cimUserInfo = new CIMUserInfo(userId, sendUserName); + return Optional.of(cimUserInfo); + } + }); + } + @Bean public ServerApi serverApi(OkHttpClient okHttpClient) { return RpcProxyManager.create(ServerApi.class, okHttpClient); diff --git a/cim-forward-route/src/main/java/com/crossoverjie/cim/route/service/impl/UserInfoCacheServiceImpl.java b/cim-forward-route/src/main/java/com/crossoverjie/cim/route/service/impl/UserInfoCacheServiceImpl.java index 2f27938c..76a1e8b7 100644 --- a/cim-forward-route/src/main/java/com/crossoverjie/cim/route/service/impl/UserInfoCacheServiceImpl.java +++ b/cim-forward-route/src/main/java/com/crossoverjie/cim/route/service/impl/UserInfoCacheServiceImpl.java @@ -2,6 +2,10 @@ import com.crossoverjie.cim.common.pojo.CIMUserInfo; import com.crossoverjie.cim.route.service.UserInfoCacheService; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @@ -11,6 +15,8 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import static com.crossoverjie.cim.route.constant.Constant.ACCOUNT_PREFIX; import static com.crossoverjie.cim.route.constant.Constant.LOGIN_STATUS_PREFIX; @@ -26,31 +32,17 @@ @Service public class UserInfoCacheServiceImpl implements UserInfoCacheService { - /** - * todo 本地缓存,为了防止内存撑爆,后期可换为 LRU。 - */ - private final static Map USER_INFO_MAP = new ConcurrentHashMap<>(64) ; - @Autowired private RedisTemplate redisTemplate ; + @Resource(name = "userInfoCache") + private LoadingCache> userInfoMap; + @Override public Optional loadUserInfoByUserId(Long userId) { - - //优先从本地缓存获取 - CIMUserInfo cimUserInfo = USER_INFO_MAP.get(userId); - if (cimUserInfo != null){ - return Optional.of(cimUserInfo); - } - - //load redis - String sendUserName = redisTemplate.opsForValue().get(ACCOUNT_PREFIX + userId); - if (sendUserName != null){ - cimUserInfo = new CIMUserInfo(userId,sendUserName) ; - USER_INFO_MAP.put(userId,cimUserInfo) ; - } - - return Optional.ofNullable(cimUserInfo); + //Retrieve user information using a second-level cache. + Optional cimUserInfo = userInfoMap.getUnchecked(userId); + return cimUserInfo; } @Override