使用场景:某平台用户搜索(search)-选择商品-下单;
本公司角色:二级代理商(在香港外包公司取得数据=美国总部一致对外公布的商品信息+香港一级代理商佣金)
业务处理流程:平台(多个)用户请求-公司请求-外包(美国+一级代理商)结果-公司处理-平台
业务流程中主要是针对用户搜索(search)带来的高并发处理进行一个记录。
解决方案:
LVS+Mencache(独立一台服务器 配置32g内存,liunx)
LVS分发到四台“服务器”(主要是服务器没有购买下来,用普通的4G内存台式电脑替换);后面服务器买了,把LVS分发去掉,直接处理请求;
期间把量加大了,公司服务器可以应付过来这么多请求,但是在外包调用返点(webserver)步骤由于并发太大,处理不过来也挂了;
解决办法
1,搭建4个webserver站点,轮询访问;
2,把数据写入缓存(计划)
改进:
后台程序跑数据写入缓存
总结:
1,由于没有大数据的并发经验,很多方案都不断的尝试,改进再测试再改进;
2,处理高并发,通过分发,减轻服务器压力;后台程序支持缓存更新;
关键代码:
Mencache :
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Configuration; 6 using Memcached.ClientLibrary; 7 8 namespace Command.Memcached 9 { 10 public class MemcachedInit 11 { 12 private static string _memname = "policypool"; 13 private static MemcachedClient _mc = new MemcachedClient(); 14 private static MemcachedInit _c = new MemcachedInit(); 15 private MemcachedInit() { } 16 17 public static MemcachedInit CurrentMemcached 18 { 19 get { 20 return _c; 21 } 22 } 23 24 public bool DeleteCache(string key) 25 { 26 return _mc.Delete(key); 27 } 28 29 public object GetCache(string key) 30 { 31 return _mc.Get(key); 32 } 33 34 public void SetCache(string key, object obj) 35 { 36 _mc.Set(key, obj); 37 } 38 39 public void SetCache(string key,object obj, DateTime dt) 40 { 41 _mc.Set(key, obj, dt); 42 } 43 44 public bool IsKeyExists(string key) 45 { 46 return _mc.KeyExists(key); 47 } 48 /// <summary> 49 /// 增加缓存 50 /// </summary> 51 /// <param name="key">Key</param> 52 /// <param name="obj">Value</param> 53 /// <param name="min">分钟数</param> 54 public void SetCache(string key, object obj, int min) 55 { 56 _mc.Set(key, obj, DateTime.Now.AddMinutes(min)); 57 } 58 59 public bool FlushAll() 60 { 61 return _mc.FlushAll(); 62 } 63 64 public void Init() 65 { 66 string[] serverlist = ConfigurationManager.AppSettings["Memcached.ServerList"].Split(','); 67 //string[] serverlist = { "127.0.0.1:11211" }; //服务器列表,可多个 68 try 69 { 70 // 初始化SocketIO池 71 string poolName = _memname; 72 SockIOPool sockIOPool = SockIOPool.GetInstance(poolName); 73 // 添加服务器列表 74 sockIOPool.SetServers(serverlist); 75 // 设置连接池初始数目 76 sockIOPool.InitConnections = 3; 77 // 设置连接池最小连接数目 78 sockIOPool.MinConnections = 3; 79 // 设置连接池最大连接数目 80 sockIOPool.MaxConnections = 5; 81 // 设置连接的套接字超时时间(单位:毫秒) 82 sockIOPool.SocketConnectTimeout = 1000; 83 // 设置套接字超时时间(单位:毫秒) 84 sockIOPool.SocketTimeout = 3000; 85 // 设置维护线程运行的睡眠时间:如果设置为0,那么维护线程将不会启动 86 sockIOPool.MaintenanceSleep = 30; 87 // 设置SockIO池的故障标志 88 sockIOPool.Failover = true; 89 // 是否用nagle算法启动 90 sockIOPool.Nagle = false; 91 // 正式初始化容器 92 sockIOPool.Initialize(); 93 94 _mc.PoolName = _memname; 95 96 _mc.EnableCompression = false; 97 } 98 catch (Exception err) 99 { 100 common.LogUtils.Debug("memcached线程启动失败 "+err.Message); 101 } 102 } 103 104 } 105 }
轮询遍历webservice
1 ServiceSoapClient client = new ServiceSoapClient(); 2 //ConfigSetting.SearchUrls 存放多个webservice地址 3 if (!string.IsNullOrEmpty(ConfigSetting.SearchUrls)) 4 { 5 client.Endpoint.Address = new System.ServiceModel.EndpointAddress(GetRandomUrl()); 6 }
1 private string GetRandomUrl() 2 { 3 string[] _urls = Regex.Split(ConfigSetting.SearchUrls, ","); 4 Random _r = new Random(); 5 int rint = _r.Next(0, 25 * _urls.Length - 1); 6 return _urls[rint % _urls.Length]; 7 }
附图: