nginx+memcached+ftp上传图片+iis
自毕业以来,一直在现在公司做订餐系统的开发,那会儿没有口碑,没有饿了么,更别说美团外卖,百度外卖了...因为规模都比较小,都是一个服务器包含数据库,iis...然后就完事儿了。终于等到给窝窝团开发订餐系统时,以为可以了解更多服务器相关东西时,生产环境我又接触不了,但还是了解了好些内容:session怎么用数据库保存,图片如何用单独服务器之类,虽然都是小儿科,但是第一次接触这些时,还是感慨良多:觉得之前都白过了。
再到后来,终于,我们的一个客户日均订单在5K时(12年时,还是蛮不错的了),我以为机会又来了,正当我满心欢喜的捣鼓两个服务器时,然后,他们告诉我们,他们用别人的系统了,然后,订单就开始少了,然后,美团到了他们的城市,然后,就没有然后了。
没有观众,再好的表演也没意义了,虽然有时也会一时兴起,搭个环境玩下,但一有问题就放弃了,毕竟没有用武之地。
终于,一个做配送的客户,每天有2K的订单了,我觉得是时候学习下《负载均衡》了,于是有了下文,鄙人也是第一次真正使用这个,不正之处,欢迎斧正。
nginx安装与配置
这部分基本操作都是差不多的,博客园也有很多文章讲解得非常详细了, 我之前也是参考这片文章,写得蛮详细的, nginx+iis实现负载均衡
配置方面,我就是 server 结节下增加了配置 server_name www.xxx.com a.xxx.com; 方便用域名访问而已。
外网无法访问?
配置完成后,在服务器上访问非常正常,用ip,域名访问也都正常,防火墙端口中也添加了例外,正当山重水复疑无路之时,才想起,早些时间配置server-u时,(如果安装时没开防火墙)要选择程序添加例外,其实,域名解析早就完成了,ping 测试正常,两个服务器单独访问也是正常,所以只有可能是防火墙的问题了,配置很简单,控制面板---windows防火墙---高级设置---入站规则---新建规则---程序---选择nginx---下一步 ....完成
设置后外网域名访问正常了
session数据库配置
使用两台服务器后,要考虑session共享的问题,之前开发时,也是使用数据库保存,稍微了解些,所以这次也使用数据库保存。
要使用数据库保存session,首先要配置数据库(废话了),其次是要在web.config中进行相关配置。
配置数据库比较简单,定位到指定.net版本,执行以下命令就可以,比如我的服务器是64位操作系统,用的.net 4.0的,以下命令如下
定位指定文件夹: cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
执行命令: aspnet_regsql.exe -S xx\sql2008 -U user -P passward -d Sessiondb -ssadd -sstype c
上面这个命令 -S 表示服务器名称,也可写ip, -U 表示用户名,-P 表示密码 -d 表示要生成的数据库名称
执行命令时,可能有些服务器会提示要在命令前加 .\ 直接加就可以了, 提示如下表示OK了,这时你发现已经自动生成了一个数据为,名称为-d 后面的名称。
接下来就是web.config配置了 在<system.web> 结点下增加如下内容
数据库链接串部分为上面生成的数据库相关信息,具体如下图
完成以上操作,就可以正常访问了,然后,搜索商家,添加购物车,提交订单等一系列订餐流程就完成了,为了方便查看,我在一个服务器上首页标题上加了一个“1”,来区分两个服务器,因为没有配置weight
所以基本是平均每个服务器请求一次。
确实订餐一系列流程都正常了,但是真的就完成了吗?其实还早着呢!
图片上传
以前单个服务器时,上传图片自己到根目录/uplpad/,路径保存成 ~/upload/201601/xxx.png,前台显示时使用 Server.MapPath(图片路径)就可以了。
分成多个服务器后,以前的方式只能把图片保存到本服务器,别的服务器就无法访问了,我参考了原来 discuz 的代码,使用ftp方式上传到远程服务器,具体操作如下:
1,选择某个服务器做为图片服务器,选择一个文件夹比如images 做为所有图片的存放的位置。
2,在IIS里搭建一个站点,根目录就是第一步中创建 images 文件夹,绑定几个域名如:img0.ihangjing.com,img1.ihangjing.com ... 图片保存时,随机选择0-x中的一个数据,这个图片最后保存的路径就是 img(n).ihangjing.com/upload/yyyyMM/xxx.png了。
3,创建一个ftp站点,根目录也是第一步中创建 images 文件夹,设置好用户名如:ftpuser,密码如:ftppwd。
4,配置ftp相关信息,具体如下图:
5,上传图片时,调用实现ftp的代码,保存文件就可以了。
FTPs ftps = new FTPs();
ftps.UpLoadFile("/"+strDay, DirUrl + "/" + tempFileName, FTPs.FTPUploadEnum.WebImg);
6,经过上面的过程,图片路径都是保存的绝对路径,这样请求图片时,不管是哪个服务器,显示都正常了。
注: ftps的代码基本是参考 discuz,做了一些调整,这里就不贴代码了,有兴趣的自己下载哈。
缓存配置 memcached
以前缓存是使用的类 System.Web.Caching.Cache 这个是保存本服务器内存的,准确的说应该是(对于每个应用程序域均创建该类的一个实例),多个服务器时,每个服务器都缓存在自己内存里,如果某个服务器数据更新,不能通知到别的服务器,那别的数据库的数据就是“脏数据”
之前微信站点,与 pc 站点就有缓存更新不及时,后来偷懒用来一个比较简单的方法处理了:pc端更新缓存时,通过http接口更新微信站点的缓存。所以,以前更新缓存要做两步:
UpdateCacheByKey("WebPromotionConfig"); //更新其他站点缓存
EasyEatCache.GetCacheService().RemoveObject("/WebPromotionConfig");//更新本站点缓存
虽然这样确实可以解决大部分的问题,但是麻烦,于是决定用 memcached 做缓存服务器,具体操作如下:
1,下载安装文件,为了大家方便我这里上传一个文件。点我下载
2,至于安装,启动这些有很多文章都写得很多详细了,大家自行搜索,我是参考的这这个文章:http://www.tuicool.com/articles/VjEvQb
其实基本也有两个操作
安装服务: memcached.exe -d install
启动服务:memcached.exe -m 1024 -d start
进入服务列表,看到服务正常运行就OK了,如下图:
因为我使用了两个服务器,所以两个服务器都安装好,并启动服务。
3,实现客户端,我使用的是 Memcached Providers,原来是用的 Memcached.ClientLibrary.dll,网站就一直无法打开,也不出错,后来查了,原来这只能在.net 2.0中使用,才果断放弃了, 通过配置文件配置使用本地缓存,还是Memcached (我们多数客户还是只用一个服务器,有这个配置主方便多了),最后代码缓存层结构如下:
4,web.config 配置 Memcached Providers,写法都差不多,以下是我自己的配置文件(亲自测试是可用的,请放心使用)
5,经过以上操作,原来项目的缓存就切换到了Memcached了。 步骤是就这几个,实际操作中还是有碰到不少问题,比如:从 Memcached.ClientLibrary 换成 Memcached Providers 后,数据一直缓存不了,最后
实在没办法了,才重起了服务,然后就好了,具体什么原因也没弄明白,重起真是个好方法。看数据缓存的日志后,心里总算踏实些了,本想弄个 memcached manager 监控下具体的数据,添加服务器已经提示用户名密码不正确
,这个就暂且放一下,后面有空了再好好研究下。如有哪个朋友了解的,请不吝赐教下哈。
订单通知商家,配送员
我们订单通知商家,配送员app是通过iis调用wcf通知到socket服务器,再由服务器推送给相应app, 有兴趣的可以看下,我之前的一个篇文章 《基于SuperSocket的IIS主动推送消息给android客户端》
现在变成多个服务器后,我只要修改下wcf的服务器ip就可以了。如下图
目前socket服务器,还是用的一个服务器,如果商家和配送员达到一定的量,单个服务器是无法支持的了,我想下一步就要考虑下socket负载均衡方面的东西了,如有哪个朋友了解的,也请不吝赐教下哈。
结语
我是第一次这样部署,在这之前真是不确定自己是否能完成这个事儿,中途也想放弃(世上无难事,只要肯放弃嘛),最后还是靠着不甘心的劲儿:有困难我们要上,没困难制造困难也要上。
虽然整理结构已经部署完成了,使用也正常了,但还有相当多的问题等着,比如,session共享用数据库好呢,还是用 Memcached 呢;这样部署后是否能支持现在的我们的客户的订单量呢...
文章到这里就完成了,觉得有帮助呢,动动手指点个赞,图个高兴;觉得写得不好,也接受拍砖哈;写得不正确的地方,请不吝赐教下哈,共同进步。
最后再吐槽一下:上次写了一篇文章 《订餐系统之同步饿了么商家订单》 被拿出首页了,一开始说是弄错了,放回去了,后来又说又弄错了,又拿出去了,我也是醉了。如果也有做这块的,大家交流下哦。