最近在看通用权限管理系统提供用户中心接口,发现有很多变化,现将个人理解分享给你们:web
用户中心对外提供了基础信息、权限的接口,刚开始的部署方式采用了以下图的方式,因为客户端及应用服务器的网络环境,接口服务器配置了多个电信运营商的网络连接;redis
最初在用户量不大的时候,调用接口时是直接访问数据库获取数据向应用服务器输出,随着客户端访问量的增大,用户中心库的压力也逐渐增大,为了保证接口的稳定性,减轻数据库压力,进行了缓存化改造,主要使用了Redis,并进行了读写分离,改造后的示意图以下:数据库
基础信息管理应用系统主要是维护基础信息、权限配置的,能够直观的看到,改造后,基础信息在更新后会将数据缓存到Redis服务器,经过Redis的主从配置,进行了读写分离,接口服务器里将原有的访问数据库获取的方法所有改造为从Redis中获取,极大的提升了效率。缓存
底层中封装好了Redis获取数据的方法,项目截图以下:服务器
提供部分参考代码以下,能够根据这个思路进行缓存优化,提升效率:网络
namespace DotNet.Business { using DotNet.Utilities; /// <summary> /// 用户数据的缓存独立库。 /// /// 修改纪录 /// /// 2016-01-07 版本:1.1 JiRiGaLa 实现读写分离。 /// 2015-04-11 版本:1.0 JiRiGaLa 建立主键。 /// /// <author> /// <name>JiRiGaLa</name> /// <date>2016-01-07</date> /// </author> /// </summary> public sealed partial class PooledRedisHelper { // Redis数据库 public static int InitialDbUser = 6; private static PooledRedisClientManager instanceUser = null; public static PooledRedisClientManager InstanceUser { get { if (instanceUser == null) { instanceUser = new PooledRedisClientManager(InitialDbUser, new string[] { BaseSystemInfo.RedisHosts }); } return instanceUser; } } public static IRedisClient GetUserClient() { return InstanceUser.GetClient(); } private static PooledRedisClientManager instanceUserReadOnly = null; public static PooledRedisClientManager InstanceUserReadOnly { get { if (instanceUserReadOnly == null) { instanceUserReadOnly = new PooledRedisClientManager(InitialDbUser, new string[] { BaseSystemInfo.RedisReadOnlyHosts }); } return instanceUserReadOnly; } } public static IRedisClient GetUserReadOnlyClient() { return InstanceUserReadOnly.GetClient(); } } }
设置和获取缓存的方法post
/// <summary> /// 获取缓存 /// </summary> /// <param name="key">缓存主键</param> /// <returns>用户信息</returns> public static BaseUserEntity GetCache(string key) { BaseUserEntity result = null; if (!string.IsNullOrWhiteSpace(key)) { // 2016-01-08 吉日嘎拉 实现只读链接,读写分离 using (var redisClient = PooledRedisHelper.GetUserReadOnlyClient()) { result = redisClient.Get<BaseUserEntity>(key); } } return result; } /// <summary> /// 获取缓存 /// 20151007 吉日嘎拉,须要在一个链接上进行大量的操做 /// </summary> /// <param name="key">缓存主键</param> /// <returns>用户信息</returns> private static BaseUserEntity GetCache(IRedisClient redisClient, string key) { BaseUserEntity result = null; if (!string.IsNullOrWhiteSpace(key)) { result = redisClient.Get<BaseUserEntity>(key); } return result; }
对外提供接口参考:优化
/// <summary> /// 用户是否在某个角色里 /// </summary> /// <param name="userInfo">用户信息</param> /// <param name="systemCode">系统编号</param> /// <param name="userId">用户主键</param> /// <param name="roleCode">角色编号</param> /// <returns>在角色里</returns> public static bool IsInRoleByCode(BaseUserInfo userInfo, string systemCode, string userId, string roleCode) { bool result = false; string url = BaseSystemInfo.UserCenterHost + "/UserCenter/UserService"; WebClient webClient = new WebClient(); NameValueCollection postValues = new NameValueCollection(); postValues.Add("system", BaseSystemInfo.SoftFullName); postValues.Add("systemCode", systemCode); postValues.Add("securityKey", BaseSystemInfo.SecurityKey); postValues.Add("function", "IsInRoleByCode"); postValues.Add("userInfo", userInfo.Serialize()); postValues.Add("userId", userId); postValues.Add("roleCode", roleCode); // 向服务器发送POST数据 byte[] responseArray = webClient.UploadValues(url, postValues); string response = Encoding.UTF8.GetString(responseArray); if (!string.IsNullOrEmpty(response)) { result = JsonConvert.DeserializeObject<bool>(response); } return result; }
经过这一番改造,各个应用系统要获取基础信息,能够直接调用底层的方法,或者经过接口获取,同时接口实现了若是缓存没有数据或数据已过时会去数据库获取,同时进行数据缓存。url