Chinaunix

标题: [讨论]从12306浅谈大型网站架构演变之路(获奖名单已公布) [打印本页]

作者: 无风之谷    时间: 2012-02-21 13:45
标题: [讨论]从12306浅谈大型网站架构演变之路(获奖名单已公布)

获奖名单已公布,详情请看:http://bbs.chinaunix.net/thread-3691073-1-1.html   

12306网的出现和产生的问题为网站架构再次提出了考验,一个好的网站构架对于网站的稳定运行至关重要,虽然我们希望网站在开始建设的时候就能有一个很好的架构,但任何事物都是在发展中不断变化的,网站架构也是随着业务的扩大、用户需求的不断改进而逐渐完善和演变的,本话题就讨论一下一个普通的网站发展成大型网站过程中网站架构的演变过程,希望从事互联网行业的朋友们畅所欲言,发表自己的意见和见解。
      这里给出现在一个大型网站的典型构架图,希望能起到抛砖引玉的作用,大家多多发言!



讨论话题:
1:谈谈自己对网站架构演变过程的理解
2:如何设计和维护一个高性能的web系统

邀请嘉宾:
      田逸:资深系统架构师
      杨向勇:51job系统运维经理
      杨海潮:新浪网架构师

活动要求:

1:针对本次话题,发表自己的意见和见解,也可提出疑问,答疑解惑!
2:分享自己对大型网站架构演变的理解
3:分享对大型网站构建、维护的经验和技巧        

讨论有奖:

        我们为参与讨论的网友准备了高俊峰《高性能Linux服务器构建实战》一书10本 作为本次活动的奖励!



作者: king_819    时间: 2012-02-21 16:18
本帖最后由 king_819 于 2012-02-21 17:51 编辑

又开始对12306进行讨论了
作者: king_819    时间: 2012-02-21 16:28
      12306有别于传统的门户网站,业务比较的简单,不是买票就是查票,所以前端压力不会太大,就算有很高的并发,通过CDN分流可以很好的解决前端访问量大的问题,对于北上广这些访问量特别大的地区,多点部署

    因为12306的数量实时性要求比较的强,数据库读写的压力将会非常的大,可以按照车次进行合理的分库,再读写分离,同样进行多点部署
作者: chenyx    时间: 2012-02-21 18:30
支持下.12306现在速度刷刷的,过年属于特殊情况,就不要再口诛笔伐了吧
作者: dooros    时间: 2012-02-21 19:06
新瓶装旧酒……其实原来两个讨论已经够了……建议开个讨论,“如何处理被黑过的服务器……”
作者: king_819    时间: 2012-02-21 20:36
架构跟业务逻辑是息息相关的,不能只单纯的看PV、看并发,空谈架构意义不大
作者: cedar_1982    时间: 2012-02-22 10:47

俺也来说说,最近做了个系统,差不多类似
首先,我个人觉得,为保证数据库的高并发性,可以按车次分数据库,每个车次得数据库做读写分离
其次,增加缓存,这个就不用说了
第三,web服务器负载均衡,可以做一个智能DNS分流,并且用集群保证数据的高可用行
作者: nicy0808    时间: 2012-02-22 11:54
这本好像是高俊峰的书
作者: huyanshu    时间: 2012-02-22 15:33
很简单,铁路售票系统在建一遍,无非就是把软件变成网页。
作者: dengbao2001    时间: 2012-02-22 17:03
期待大家分享下!

过年回家订票真不容易
作者: jingyury    时间: 2012-02-22 17:53
很贴合实际,有有参考价值~!
作者: q645278776    时间: 2012-02-22 17:58
书很不错,
作者: qiuyepiaoling    时间: 2012-02-22 18:00
嗯,大部分公司都是这样的架构
作者: a2433    时间: 2012-02-22 18:01
上面说按车次 估计不大现实  太麻烦了   我想是不是按 铁路局  划分呢   按照所选的车次 自动或者  地点  自动转到 所属铁路局  呢  12306  和各个铁路局共同担负 负载呢
作者: sery    时间: 2012-02-22 18:09
12306使用网宿的cdn,但从它的具体情况得知大部分是动态对象,不适合网宿那种加速方式。本来访问的用户多,再加上大量的cdn回源,更加重了源站的负担。回复 3# king_819


   
作者: sery    时间: 2012-02-22 18:11
12306用的数据库应该是sybase,因为售票系统一直就是sybase。12306只是用户前端,数据库应该还是那个售票系统的数据库,因此不可能另搞一套mysql回复 1# 无风之谷


   
作者: sery    时间: 2012-02-22 18:12
这个是靠谱的,可参照银行的做法回复 14# a2433


   
作者: hbsycw    时间: 2012-02-22 18:14
个人认为:

网站架构,如果单从WEB系统技术架构来讲,对于“大容量,高并发”,可以采用集群(WEB Clusters+APP Clusters+DB Clusters)方案,来有效分解压力,提高系统吞吐量。这方面业界技术上方案应该比较多,也比较成熟。但,应该认识到12306网站的特殊性,瞬间并发量大,而票资源的稀缺性又是唯一的,这显然有别于一般的EC(电子商务)。12306的业务逻辑应该不复杂,那么12306的拥堵是不是因为票资源的不足引发的呢?如果是,就应该从数据库端的资源分布、压力分解入手,数据库端的资源并发应该是一大问题,如何减少并发量而引起的整个系统性能指数级下降,应该是12306需要解决的棘手问题!

以上是个人观点,如有不同见解,欢迎拍砖,本人在此抛砖引玉~
作者: sery    时间: 2012-02-22 18:21
说得有理。但根子上的问题是压根不注重用户体验,只对上级领到负责回复 18# hbsycw


   
作者: hbsycw    时间: 2012-02-22 18:27
打油诗一首:12306 你到底是神马问题?

12306缺钱吗?
显然不缺,
如果12306不缺钱,
那么12306缺技术方案吗?
显然不是,
那么12306到底是神马问题?

显然,12306就不单纯的是一个技术问题~

作者: king_819    时间: 2012-02-22 18:34
本帖最后由 king_819 于 2012-02-22 18:35 编辑
a2433 发表于 2012-02-22 18:01
上面说按车次 估计不大现实  太麻烦了   我想是不是按 铁路局  划分呢   按照所选的车次 自动或者  地点  自 ...


要求数据库的实时性很强,主要的压力在数据库了,按铁路局划分可以减轻前端的压力(这跟民航对外提供API接口道理是一样的),进行前端分流,然后再按车次分库,这样就可以减轻数据库的压力
作者: qzbqzj    时间: 2012-02-22 18:37
12306 急需解决 千万级并发的问题...他的架构也是采用大部分站点一样的分布式架构方案!但是作为中国的“12306”应该有自己的特色,而不是效仿!
那为看假合理的架构为什么还会出现这种问题?应用瓶颈在什么地方?重点是在数据库这块。。。。
作者: qzbqzj    时间: 2012-02-22 18:44
田老师说了。。他的数据库采用sybase。。。。这是大多数售票系统所采用的!!为何底层不采用Oracle?
还有。。。。服务上用得不到位。。。。这也许是他们认为不可能有这么高的流量!导致决策失误!
所以用N+1有web服务器+  N+1 的数据库。。。。。。。。重点在数据库这块和后端存储这块下功夫!!减轻后端存储的频繁访问!!!!
作者: 南非蚂蚁    时间: 2012-02-22 18:46
看了大家的回复,都说的很有道理!

12306出现的问题是技术和管理方面不协调的结果,技术是手段,技术+管理才是战略,作为技术人员,我们能做的就是如何做好技术方面的工作。

如大家所说,12306网站的压力在于数据库方面的读查询和写订票,所以对数据库方面做规划和部署就显得至关重要,对数据库做优化是最起码的要求,其次从架构上,对数据库做读写分离部署是核心,然后还可以对数据库读操作做负载均衡,写操作做HA,这样从访问性能和安全性方面都有了一定保障,当然这一切都是在网站程序最优状态下进行的。

12306网站后台数据库应该是sysbase,其实个人认为mysql也足以支持,主要问题在于如何构架啦。

先说这么多,大家继续讨论!
作者: king_819    时间: 2012-02-22 18:54
很多行政、事业机构都是用的sysbase数据库
作者: QQ_921    时间: 2012-02-22 19:16
本帖最后由 QQ_921 于 2012-02-22 19:25 编辑

硬件方面(不考虑钱)
1、网络环境全部以光网络为主。
2、服务器可以针对系统不同,提供定制化的服务器设计。
3、存储以SAN网络为主。

软件方面
使用成熟的各种软件,这个不用多说,现在有很多成型的东西,大家都在用。
我想说的是,未来的发展,需要软件公司针对不同系统进行定制的软件平台包,需求由用户提或者根据系统特性进行设计(从OS 、中间件、DB)。

运维工程师不在是各种软硬件的安装、配置、优化,未来还需要的是定制开发能力,CENTOS 已经开始针对基于LINUX的WEB系统提供LAMP、LNMP的安装集成包了,很能说明定制的未来趋势。谁的运维团队有定制能力,类似GOOGLE的,谁就有可以设计出更好的系统。

我认为未来应该是定制系统平台的天下。
作者: 1059326068    时间: 2012-02-22 19:29
搭建该12306平台,需做评估可靠性,如本地运行等待时间、数据传输过程总时间等,待确定了实施的最佳方案,就评估时要考虑的因素包括性能、可靠性、创建实例的速度、价格、及一些相关流程等.
作者: kns1024wh    时间: 2012-02-22 21:27
回复 1# 无风之谷
数据库大会 建议吧  12360的官员请来发表个定论

   
作者: liang3391    时间: 2012-02-23 08:45
本帖最后由 liang3391 于 2012-02-23 08:46 编辑

不讨论12306的管理 只对他们的技术进行讨论。所有的一切都应该基于缓存。缓存才是能解决问题的王道。数据库是很脆弱的,不能直接和数据库打交道。什么lvs 啥的  那是必须的,web层面的其实不难,关键是数据库这块的压力。无非是加缓存机制,海量数据处理方案,不能让请求直接回源操作。NOSQL等都是可以的,要想网站承载用户并发够大,那么务必不让用户的请求直接打到指挥中心来(源服务器)这样才能提高网站的处理能力。基于程序的缓存和优化,基于硬件服务器的缓存和优化架构等措施。
作者: qzbqzj    时间: 2012-02-23 08:53
要是自己有实力。。。哈哈。。。。自已二次开发mysql数据库也不错!!把数据库层做强做精!
作者: qzbqzj    时间: 2012-02-23 09:14
回复 19# sery


    呵呵。。是的!没有做长期的打算。。他们也只是为了那么几个星期而搞那么大而不优的系统,大部分时间都在闲着,哈哈。。。。这也就铁路局才干得出。。。。。。。
作者: king_819    时间: 2012-02-23 09:27
回复 29# liang3391

12306数据库的实时性要求非常高的,数据实时刷新的,还缓存,怎么缓存

   
作者: king_819    时间: 2012-02-23 09:30
回复 14# a2433


    就算按铁路局划分,前端是可以进行分流,但后端还不是一样读取同样的数据库,如果说按铁路局划分数据库,其实跟按车次划分一样的道理!
作者: qzbqzj    时间: 2012-02-23 10:07
回复 5# dooros


    支持!!!!!!!!!!!
作者: hbsycw    时间: 2012-02-23 11:40
回复 33# king_819

按铁路局划分应该行不通,因为各个铁路局是要共享售票信息的,按车次基本靠谱,大家买票也是查询车次的吧~


   
作者: hbsycw    时间: 2012-02-23 11:46
回复 19# sery

是的,12306更应该做的是业务流程优化,系统设计应该做到主动为用户服务,以减少拥堵而造成的系统性能急速下降“雪崩效应”


   
作者: king_819    时间: 2012-02-23 11:48
回复 35# hbsycw


     按铁路局划分主要是像智能DNS一样,你在哪个省就把你的请求转到哪个省铁路局的网站上,相当于减轻了前端的压力,其实后端所有的铁路局都是访问同样的数据库,那么就再按车次,或者按次所属的铁路局进行分库,这样就减轻了数据库的压力

   
作者: hbsycw    时间: 2012-02-23 11:50
回复 29# liang3391


系统架构就是管理,没有管理的思想,是做不好架构的~


   
作者: hbsycw    时间: 2012-02-23 12:04
回复 37# king_819

12306的问题,正如大家所讨论的,问题不在于前端而在于后端,前端要增加空间,只需提高带宽,12306不缺钱。因此,后端数据库资源瓶颈应该是问题的关键。因为,12306只是给大家提供了一个新的购票渠道,实际上应该这个WEB系统是访问铁路内部的信息系统(铁路内部的ERP,具体叫什么,不是很清楚,反正得有这么一套系统),这套系统才是问题的关键,供全国的铁路局售票窗口访问,而票资源是要全局共享的,这个并发事务的压力,可想而知。因此,对12306的表现,我并不是否定的,显然,需要改造的是铁路内部的信息系统性能,管理才是关键!


   
作者: 南非蚂蚁    时间: 2012-02-24 20:14
hbsycw 发表于 2012-02-23 12:04
回复 37# king_819

12306的问题,正如大家所讨论的,问题不在于前端而在于后端,前端要增加空间,只需提 ...



改进购票业务系统是核心,也是根本,后端数据库压力首先要通过业务流程去优化,然后才是做系统架构设计
作者: melofy    时间: 2012-02-24 20:34
现在12306访问主要瓶颈在数据库访问上,可以在中间件上下功夫,各地分布中间件,适当的数据缓存,每一定时间整体把一类操作发送到服务器,处理完成,反回后分发。
解决频繁的响应带来的压力
作者: 南非蚂蚁    时间: 2012-02-24 20:53
melofy 发表于 2012-02-24 20:34
现在12306访问主要瓶颈在数据库访问上,可以在中间件上下功夫,各地分布中间件,适当的数据缓存,每一定时间 ...



缓存,读写分离,负载均衡,这是构建的基础。数据库其实很脆弱的
作者: 南非蚂蚁    时间: 2012-02-24 21:15
king_819 发表于 2012-02-23 11:48
回复 35# hbsycw  



按照车次靠谱,但是按照铁路局不太现实,以现在铁路局的环境来讲!
作者: 齐达内553847981    时间: 2012-02-24 21:19
      前端应该有 CDN,尽量将静态内容放到这一级,并配合其他CDN的应用模式;下一级负载均衡应该是DNS,将流量均匀分配到不同的IP;再下一级应该是LVS,将访问请求分发到不同的物理服务器,然后再下一层才是存储层。
      采用N个服务器M个数据库的架构方式。将服务器与数据库分开,N个服务器皆可访问M个数据库。服务器负责处理不同物理链路上的请求,服务器上采用任务均衡迁移服务,同时负责与各个数据库交互。
      瓶颈在数据库。尽可能减少到达存储层的访问请求,这才是12306问题的关键所在。12306底层的数据库应首选Oracle.

作者: daocaoren0311    时间: 2012-02-24 21:30
网站架构的变迁和业务是息息相关的。一般是随着业务量增大而变化。开始的时候也许就1个web 1个db ,随着并发量的增大 2个web 1个db  ,然后是变为两个负载均衡器 和多个web 1个db,然后是db 主从复制,读写分离,图片等静态图片分离。然后会多些缓存服务器 如squid varnish等。然后是cdn,多机房,分布式 文件系统 等。 最终压力 都会在数据库 可能会拆分,无论是垂直还是水平。我感觉12326 这样的问题,可以托管。比方说给阿里,或者腾讯,既然我们水平有限 。就让牛人来处理吧。
作者: 346196247    时间: 2012-02-25 13:02
回复 6# king_819


    就是每秒50人访问你的网站1台服务器吃的消吗?
作者: hbsycw    时间: 2012-02-25 21:50
回复 45# daocaoren0311

12306暴露出来的是铁路系统的整个售票系统需要提高,这个系统的并发量和复杂度不是阿里可比的~


   
作者: hbsycw    时间: 2012-02-25 21:58
本帖最后由 hbsycw 于 2012-02-27 13:56 编辑
南非蚂蚁 发表于 2012-02-24 20:14
改进购票业务系统是核心,也是根本,后端数据库压力首先要通过业务流程去优化,然后才是做系统架构设 ...



是的,资深人士对问题的认识就是不一样,12306只是个新的购票渠道和窗口(相当于一个开放的虚拟铁路局售票窗口),12306的瓶颈暴露出的是铁路内部的售票系统整体有待提升, 而对业务流程的重构应该是技术提升的前提~
作者: fire_cpp    时间: 2012-02-26 15:49
hbsycw 发表于 2012-02-22 18:27
打油诗一首:12306 你到底是神马问题?

12306缺钱吗?


他们确实不缺钱,但我觉得有可能缺技术,或者说经验。
网站是原来开发老系统那帮人做的(其实老系统还是不错的,支持起了整个业务),但他们可能缺乏互联网上大并发架构的经验。
虽不是隔行,但互联网的环境绝对不同于售票网点的环境。只能说,他们落后于时代了。
作者: caozhangming    时间: 2012-02-27 13:32
本帖最后由 caozhangming 于 2012-02-27 13:45 编辑

菜鸟对各位LZ所说的做个小总结,~ ~

12306网站特征:高并发、大容量、数据要求实时一致,重点在数据库

1、首先对12306的静态的内容,可以利用CDN进行缓存。
2、前端WEB采用集群、对数据库做读写分离部署,然后还可以对数据库读操作做负载均衡,写操作做HA
3、后端存储以SAN网络为主。
DB的前面也可以考虑用MEMCACHE来缓存部分数据,如:只查有无售票的数据、票的价格、时间等等
作者: 南非蚂蚁    时间: 2012-02-28 09:00
本帖最后由 南非蚂蚁 于 2012-02-28 13:51 编辑

这里总结下网站架构的演变过程:


架构演变第一步:物理分离webserver和数据库



架构演变第二步:增加页面缓存


架构演变第三步:增加页面片段缓存

作者: 南非蚂蚁    时间: 2012-02-28 09:07
本帖最后由 南非蚂蚁 于 2012-02-28 13:52 编辑

架构演变第四步:数据缓存



架构演变第五步:前段增加webserver


架构演变第六步:数据库分库


作者: hbsycw    时间: 2012-02-28 12:51
回复 52# 南非蚂蚁

个人习惯的架构是:WEB Server+APP Server+DB Server, 然后每层再有针对性的实施水平扩展(SCALE OUT)方案。


   
作者: ak47mig    时间: 2012-02-28 13:04
king_819 发表于 2012-02-23 09:27
回复 29# liang3391

12306数据库的实时性要求非常高的,数据实时刷新的,还缓存,怎么缓存



说到缓存。其实得根据买票这个业务来具体的看。

数据是实时刷新的,但是除非购买,不用真正跟数据库交互。
如果只是查询。一秒钟更新一次缓存也足够了,真正订票的时候大家一秒钟并发很高的。


作者: ak47mig    时间: 2012-02-28 13:08
a2433 发表于 2012-02-22 18:01
上面说按车次 估计不大现实  太麻烦了   我想是不是按 铁路局  划分呢   按照所选的车次 自动或者  地点  自 ...


按车次分还好吧。

我觉得我们在这里讨论也是外人指路,最好还是有12306的日志看看,哪些车次是高频率车次。或者根据铁路局之前的经验来看,哪些线路可能订票比较多。对于热点线路单独分一个库我觉得是不为过的。

一些非热点线路可以根据负载情况分到其他库里。

另外很可能一个线路今天几个小时就售罄了这个时候数据库就空闲了。可以移出。
作者: ak47mig    时间: 2012-02-28 13:14
sery 发表于 2012-02-22 18:09
12306使用网宿的cdn,但从它的具体情况得知大部分是动态对象,不适合网宿那种加速方式。本来访问的用户多, ...

对。这种cdn的使用方法还是很傻的。


可能是他们一开始也没估算好。在设计的时候没有完全把动静态分开。

把静态资源上cdn,保证用户的浏览正常,尽量做小动态资源部分。我觉得从设计上还是可以把动态资源做到最小的。

另外刚才提到的一个极端方法:一个线路一个数据库,我觉得在cdn上也可以做类似的考虑。比如剩余票数查询完全可以跟cdn商协商。也是一秒钟一更新跟源站取数据,但是坚决避免除此之外的回源。

真正让网站把资源节省到用户订票的写操作上。
作者: ak47mig    时间: 2012-02-28 13:20
南非蚂蚁 发表于 2012-02-28 09:07
数据缓存


其实原理也就是cache,更多的cache和分拆,更合理的分拆。

楼主的哪个设计只是保证了基本的性能和基础的冗余性。如果运算本身就是很多,还是需要将负担放在更多机器上去的。所以就是分拆,分库。

我们不可能把用户的需求减少:只能将请求减轻(更小数据个头的数据量请求,将静态请求剥离),更浅(比如非写入的尽量落到更靠前的cache上)。


另外其实app和database的优化在这个时候可能也会更有效一些。

比如是否能把update改成别的方式。起码mysql的update肯定容易锁表的。数据库里面的数据能否只是简单的数据符号。
作者: ak47mig    时间: 2012-02-28 13:27
齐达内553847981 发表于 2012-02-24 21:19
前端应该有 CDN,尽量将静态内容放到这一级,并配合其他CDN的应用模式;下一级负载均衡应该是DNS,将 ...


我倒觉得数据库不一定非得选oracle....当然最终的存储选择oracle是没问题的,但是订票时段并发太高,oracle性能不适合吧。


其实对于车票这种特殊的应用,我觉得可能自己写个特殊的数据库放在订票时段用更合适一些。因为车票的特点就是一个人一个坑,一个车次总坑数是一定的。


而对于订票来说,订票时间写入是高峰,这个写入只是说让你入坑而已。所以我觉得不如很多东西错峰来做(比如校验用户的真实性,生成车票相关信息之类的):订票的时候就是让这些人入坑(可以只是简单的打log,或者数据库的insert操作,但是会判断有座无座以免卖超了)。然后等低峰的时候慢慢从log里回放,让大家选座之类的。这些最终信息再慢慢入总库。
作者: 南非蚂蚁    时间: 2012-02-28 13:38
ak47mig 发表于 2012-02-28 13:20
其实原理也就是cache,更多的cache和分拆,更合理的分拆。

楼主的哪个设计只是保证了基本的性能和基 ...



分析的很有道理,感谢分享经验!
作者: 南非蚂蚁    时间: 2012-02-28 13:40
本帖最后由 南非蚂蚁 于 2012-02-28 13:47 编辑

继续接52楼

架构演变第七步:分表、DAL和分布式缓存





架构演变第八步:增加更多的webserver,分布式文件系统




架构演变第九步:数据读写分离加廉价存储方案


作者: ak47mig    时间: 2012-02-28 14:12
ak47mig 发表于 2012-02-28 13:27
我倒觉得数据库不一定非得选oracle....当然最终的存储选择oracle是没问题的,但是订票时段并发太高,or ...


针对业务的数据库调优其实还是很重要的。我们现在就有一个库,里面性能问题在于大量的update。在一个很大的库表中update,导致我们现在主从都无法同步上。

所以下次架构升级就要改这个东西,让库先只insert。。。

这个应用现在每秒300次请求的,每次请求都有数据写入。
作者: 南非蚂蚁    时间: 2012-02-28 14:54
ak47mig 发表于 2012-02-28 14:12
针对业务的数据库调优其实还是很重要的。我们现在就有一个库,里面性能问题在于大量的update。在一个很 ...



是的,对业务流程调优是非常重要的,业务流程不合理,针对数据库、系统架构优化都很有限!
作者: spark8103    时间: 2012-03-01 10:08
业务逻辑在那呢,分流是最好了,数据库进行水平分割!
作者: hbsycw    时间: 2012-03-05 21:06
spark8103 发表于 2012-03-01 10:08
业务逻辑在那呢,分流是最好了,数据库进行水平分割!


是啊,可以分而治之!
作者: spv999    时间: 2012-03-06 09:30
是不是真的啊我回复了啊
书书快到手
作者: xdbeyond    时间: 2012-03-06 09:30
可以优化、规范各业务URI,在代理层实现业务的划分,可用的技术有Haproxy、Nginx等,如将/otsweb/regitNote/映射到注册组WEB服务器,/otsweb/AppQuery/映射到查询组WEB服务器,/otsweb/Pay/映射到支付组WEB服务器等等,如此一来,当查询业务出现延时堵塞时不会影响到用户支付。


   
作者: jjsly11    时间: 2012-03-06 09:33
我觉得,铁路订票系统关键在于高并发,服务器的质量提高不用说,另外,各地分流,智能dns ,数据库的压力很大,人太多了。如何尽量优化数据结构和多服务器负载均衡是重点了。
作者: liu5620481    时间: 2012-03-06 09:35
现在正在学习系统架构中,目前只会搭建一些简单的架构,不过12306这个网站,确实够烂的。是该好好改改了
作者: liu5620481    时间: 2012-03-06 09:36
12306,去年过年前,着实让中国人蛋疼了几天
作者: aha45678    时间: 2012-03-06 09:39
网站架构真的不懂,一直在学习中,望蚂蚁哥能支援一本,有能力再积极参加你的活动。
作者: a357316602    时间: 2012-03-06 09:46
1.应用分层(便于随时的增删服务器以及更好的维护性)
2.对于12306此类网站查询 订购应该分离
   a.查询余票采用一个数据集群处理系统
   b.订票采用一个数据集群处理系统
3.分离静态页面 css js 图片等
4.能够使用缓存的地方尽量使用缓存服务


小弟对于这块的了解目前也只限于这个层次有错误的地方希望大家指点批评,谢谢.

作者: liu5620481    时间: 2012-03-06 09:46
关于高并发,我大概了解的就是通过分布式服务器去分摊压力,不过中国的网速还是一大问题,中小城市的家庭网速慢的可怜
作者: learnbank    时间: 2012-03-06 09:53
不错的书,看看。赞一下。
作者: hb117715785    时间: 2012-03-06 09:53
不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略。
作者: whatislinux    时间: 2012-03-06 10:15

1,静态与动态分离,减小服务器的负载。
2,应用分层,便于服务器的管理以及应用的维护。
3,尽最大可能利用缓存技术


作者: hbsycw    时间: 2012-03-06 16:17
回复 74# hb117715785

是的,要有专门的文件服务器~


   
作者: zhanqitan    时间: 2012-03-07 09:47
分享下,求书学习!!
作者: wenzizone    时间: 2012-03-08 10:58
1230**网站挂了,被全国人民骂了。我这两天也在思考这个事,我想以这个事来粗略地和大家讨论一下网站性能的问题。因为仓促,而且完全基于本人有限的经验和了解,所以,如果有什么问题还请大家一起讨论和指正。(这又是一篇长文,只讨论性能问题,不讨论那些UI,用户体验,或是是否把支付和购票下单环节分开的功能性的东西)

业务

任何技术都离不开业务需求,所以,要说明性能问题,首先还是想先说说业务问题。

其一,有人可能把这个东西和QQ或是网游相比。但我觉得这两者是不一样的,网游和QQ在线或是登录时访问的更多的是用户自己的数据,而订票系统访问的是中心的票量数据,这是不一样的。不要觉得网游或是QQ能行你就以为这是一样的。网游和QQ 的后端负载相对于电子商务的系统还是简单。
其二,有人说春节期间订火车的这个事好像网站的秒杀活动。的确很相似,但是如果你的思考不在表面的话,你会发现这也有些不一样。火车票这个事,还有很多查询操作,查时间,查座位,查铺位,一个车次不 行,又查另一个车次,其伴随着大量的查询操作,下单的时候需要对数据库操作。而秒杀,直接杀就好了。另外,关于秒杀,完全可以做成只接受前N个用户的请求(完全不操作后端的任何数据, 仅仅只是对用户的下单操作log),这种业务,只要把各个服务器的时间精确同步了就可以了,无需在当时操作任何数据库。可以订单数够后,停止秒杀,然后批量写数据库。火车票这个岂止是秒杀那么简单。能不能买到票得当时告诉用户啊。
其三,有人拿这个系统和奥运会的票务系统比较。我觉得还是不一样。虽然奥运会的票务系统当年也一上线就废了。但是奥运会用的是抽奖的方式,也就是说不存在先来先得的抢的方式,而且,是事后抽奖,事前只需要收信息,事前不需要保证数据一致性,没有锁,很容易水平扩展。
其四,订票系统应该和电子商务的订单系统很相似,都是需要对库存进行:1)占住库存,2)支付(可选),3)扣除库存的操作。这个是需要有一致性的检查的,也就是在并发时需要对数据加锁的。B2C的电商基本上都会把这个事干成异步的,也就是说,你下的订单并不是马上处理的,而是延时处理的,只有成功处理了,系统才会给你一封确认邮件说是订单成功。我相信有很多朋友都收到认单不成功的邮件。这就是说,数据一致性在并发下是一个瓶颈。

其五,铁路的票务业务很变态,其采用的是突然放票,而有的票又远远不够大家分,所以,大家才会有抢票这种有中国特色的业务的做法。于是当票放出来的时候,就会有几百万人甚至上千万人杀上去,查询,下单。几十分钟内,一个网站能接受几千万的访问量,这个是很恐怖的事情。据说12306的高峰访问是10亿PV,集中在早8点到10点,每秒PV在高峰时上千万。
多说几句:

库存是B2C的恶梦,库存管理相当的复杂。不信,你可以问问所有传统和电务零售业的企业,看看他们管理库存是多么难的一件事。不然,就不会有那么多人在问凡客的库存问题了。(你还可以看看《乔布斯传》,你就知道为什么Tim会接任Apple的CEO了,因为他搞定了苹果的库存问题)
对于一个网站来说,浏览网页的高负载很容易搞定,查询的负载有一定的难度去处理,不过还是可以通过缓存查询结果来搞定,最难的就是下单的负载。因为要访问库存啊,对于下单,基本上是用异步来搞定的。去年双11节,淘宝的每小时的订单数大约在60万左右,京东一天也才能支持40万(居然比12306还差),亚马逊5年前一小时可支持70万订单量。可见,下订单的操作并没有我们相像的那么性能高。
淘宝要比B2C的网站要简单得多,因为没有仓库,所以,不存在像B2C这样有N个仓库对同一商品库存更新和查询的操作。下单的时候,B2C的 网站要去找一个仓库,又要离用户近,又要有库存,这需要很多计算。试想,你在北京买了一本书,北京的仓库没货了,就要从周边的仓库调,那就要去看看沈阳或 是西安的仓库有没有货,如果没有,又得看看江苏的仓库,等等。淘宝的就没有那么多事了,每个商户有自己的库存,库存分到商户头上了,反而有利于性能。
数据一致性才是真正的性能瓶颈。有 人说nginx可以搞定每秒10万的静态请求,我不怀疑。但这只是静态请求,理论值,只要带宽、I/O够强,服务器计算能力够,并支持的并发连接数顶得住10万TCP链接的建立 的话,那没有问题。但在数据一致性面前,这10万就完完全全成了一个可望不可及的理论值了。
我说那么多,我只是想从业务上告诉大家,我们需要从业务上真正了解春运铁路订票这样业务的变态之处。

前端性能优化技术

要解决性能的问题,有很多种常用的方法,我在下面列举一下,我相信12306这个网站使用下面的这些技术会让其性能有质的飞跃。

一、前端负载均衡
通过DNS的负载均衡器(一般在路由器上根据路由的负载重定向)可以把用户的访问均匀地分散在多个Web服务器上。这样可以减少Web服务器的请求负载。因为http的请求都是短作业,所以,可以通过很简单的负载均衡器来完成这一功能。最好是有CDN网络让用户连接与其最近的服务器(CDN通常伴随着分布式存储)。(关于负载均衡更为详细的说明见“后端的负载均衡”)

二、减少前端链接数
我看了一下1230**,打开主页需要建60多个HTTP连接,车票预订页面则有70多个HTTP请求,现在的浏览器都是并发请求的。所以,只要有100万个用户,就会有6000万个链接,太多了。一个登录查询页面就好了。把js打成一个文件,把css也打成一个文件,把图标也打成一个文件,用css分块展示。把链接数减到最低。

三、减少网页大小增加带宽
这个世界不是哪个公司都敢做图片服务的,因为图片太耗带宽了。现在宽带时代很难有人能体会到当拨号时代做个图页都不敢用图片的情形(现在在手机端浏览也是这个情形)。我查看了一下12306首页的需要下载的总文件大小大约在900KB左右,如果你访问过了,浏览器会帮你缓存很多,只需下载10K左右的文件。但是我们可以想像一个极端一点的案例,1百万用户同时访问,且都是第一次访问,每人下载量需要1M,如果需要在120秒内返回,那么就需要,1M * 1M /120 * 8 = 66Gbps的带宽。很惊人吧。所以,我估计在当天,12306的阻塞基本上应该是网络带宽,所以,你可能看到的是没有响应。后面随着浏览器的缓存帮助12306减少很多带宽占用,于是负载一下就到了后端,后端的数据处理瓶颈一下就出来。于是你会看到很多http 500之类的错误。这说明服务器垮了。

四、前端页面静态化
静态化一些不常变的页面和数据,并gzip一下。还有一个并态的方法是把这些静态页面放在/dev/shm下,这个目录就是内存,直接从内存中把文件读出来返回,这样可以减少昂贵的磁盘I/O。

五、优化查询
很多人查询都是在查一样的,完全可以用反向代理合并这些并发的相同的查询。这样的技术主要用查询结果缓存来实现,第一次查询走数据库获得数据,并把数据放到缓存,后面的查询统统直接访问高速缓存。为每个查询做Hash,使用NoSQL的技术可以完成这个优化。(这个技术也可以用做静态页面)

对于火车票量的查询,个人觉得不要显示数字,就显示一个“有”或“无”就好了,这样可以大大简化系统复杂度,并提升性能。

六、缓存的问题
缓存可以用来缓存动态页面,也可以用来缓存查询的数据。缓存通常有那么几个问题:

1)缓存的更新。也叫缓存和数据库的同步。有这么几种方法,一是缓存time out,让缓存失效,重查,二是,由后端通知更新,一量后端发生变化,通知前端更新。前者实现起来比较简单,但实时性不高,后者实现起来比较复杂 ,但实时性高。

2)缓存的换页。内存可能不够,所以,需要把一些不活跃的数据换出内存,这个和操作系统的内存换页和交换内存很相似。FIFO、LRU、LFU都是比较经典的换页算法。相关内容参看Wikipeida的缓存算法。

3)缓存的重建和持久化。缓存在内存,系统总要维护,所以,缓存就会丢失,如果缓存没了,就需要重建,如果数据量很大,缓存重建的过程会很慢,这会影响生产环境,所以,缓存的持久化也是需要考虑的。

诸多强大的NoSQL都很好支持了上述三大缓存的问题。

后端性能优化技术

前面讨论了前端性能的优化技术,于是前端可能就不是瓶颈问题了。那么性能问题就会到后端数据上来了。下面说几个后端常见的性能优化技术。

一、数据冗余
关于数据冗余,也就是说,把我们的数据库的数据冗余处理,也就是减少表连接这样的开销比较大的操作,但这样会牺牲数据的一致性。风险比较大。很多人把NoSQL用做数据,快是快了,因为数据冗余了,但这对数据一致性有大的风险。这需要根据不同的业务进行分析和处理。(注意:用关系型数据库很容易移植到NoSQL上,但是反过来从NoSQL到关系型就难了)

二、数据镜像
几乎所有主流的数据库都支持镜像,也就是replication。数据库的镜像带来的好处就是可以做负载均衡。把一台数据库的负载均分到多台上,同时又保证了数据一致性(Oracle的SCN)。最重要的是,这样还可以有高可用性,一台废了,还有另一台在服务。

数据镜像的数据一致性可能是个复杂的问题,所以我们要在单条数据上进行数据分区,也就是说,把一个畅销商品的库存均分到不同的服务器上,如,一个畅销商品有1万的库存,我们可以设置10台服务器,每台服务器上有1000个库存,这就好像B2C的仓库一样。

三、数据分区
数据镜像不能解决的一个问题就是数据表里的记录太多,导致数据库操作太慢。所以,把数据分区。数据分区有很多种做法,一般来说有下面这几种:

1)把数据把某种逻辑来分类。比如火车票的订票系统可以按各铁路局来分,可按各种车型分,可以按始发站分,可以按目的地分……,反正就是把一张表拆成多张有一样的字段但是不同种类的表,这样,这些表就可以存在不同的机器上以达到分担负载的目的。

2)把数据按字段分,也就是竖着分表。比如把一些不经常改的数据放在一个表里,经常改的数据放在另外多个表里。把一张表变成1对1的关系,这样,你可以减少表的字段个数,同样可以提升一定的性能。另外,字段多会造成一条记录的存储会被放到不同的页表里,这对于读写性能都有问题。但这样一来会有很多复杂的控制。

3)平均分表。因为第一种方法是并不一定平均分均,可能某个种类的数据还是很多。所以,也有采用平均分配的方式,通过主键ID的范围来分表。

4)同一数据分区。这个在上面数据镜像提过。也就是把同一商品的库存值分到不同的服务器上,比如有10000个库存,可以分到10台服务器上,一台上有1000个库存。然后负载均衡。

这三种分区都有好有坏。最常用的还是第一种。数据一旦分区,你就需要有一个或是多个调度来让你的前端程序知道去哪里找数据。把火车票的数据分区,并放在各个省市,会对12306这个系统有非常有意义的质的性能的提高。

四、后端系统负载均衡
前面说了数据分区,数据分区可以在一定程度上减轻负载,但是无法减轻热销商品的负载,对于火车票来说,可以认为是大城市的某些主干线上的车票。这就需要使用数据镜像来减轻负载。使用数据镜像,你必然要使用负载均衡,在后端,我们可能很难使用像路由器上的负载均衡器,因为那是均衡流量的,因为流量并不代表服务器的繁忙程度。因此,我们需要一个任务分配系统,其还能监控各个服务器的负载情况。

任务分配服务器有一些难点:

负载情况比较复杂。什么叫忙?是CPU高?还是磁盘I/O高?还是内存使用高?还是并发高?还是内存换页率高?你可能需要全部都要考虑。这些信息要发送给那个任务分配器上,由任务分配器挑选一台负载最轻的服务器来处理。
任务分配服务器上需要对任务队列,不能丢任务啊,所以还需要持久化。并且可以以批量的方式把任务分配给计算服务器。
任务分配服务器死了怎么办?这里需要一些如Live-Standby或是failover等高可用性的技术。我们还需要注意那些持久化了的任务的队列如何转移到别的服务器上的问题。
我看到有很多系统都用静态的方式来分配,有的用hash,有的就简单地轮流分析。这些都不够好,一个是不能完美地负载均衡,另一个静态的方法的致命缺陷是,如果有一台计算服务器死机了,或是我们需要加入新的服务器,对于我们的分配器来说,都需要知道的。

还有一种方法是使用抢占式的方式进行负载均衡,由下游的计算服务器去任务服务器上拿任务。让这些计算服务器自己决定自己是否要任务。这样的好处是可以简化系统的复杂度,而且还可以任意实时地减少或增加计算服务器。但是唯一不好的就是,如果有一些任务只能在某种服务器上处理,这可能会引入一些复杂度。不过总体来说,这种方法可能是比较好的负载均衡。

五、异步、 throttle 和 批量处理
异步、throttle(节流阀) 和批量处理都需要对并发请求数做队列处理的。

异步在业务上一般来说就是收集请求,然后延时处理。在技术上就是可以把各个处理程序做成并行的,也就可以水平扩展了。但是异步的技术问题大概有这些,a)被调用方的结果返回,会涉及进程线程间通信的问题。b)如果程序需要回滚,回滚会有点复杂。c)异步通常都会伴随多线程多进程,并发的控制也相对麻烦一些。d)很多异步系统都用消息机制,消息的丢失和乱序也会是比较复杂的问题。
throttle 技术其实并不提升性能,这个技术主要是防止系统被超过自己不能处理的流量给搞垮了,这其实是个保护机制。使用throttle技术一般来说是对于一些自己无法控制的系统,比如,和你网站对接的银行系统。
批量处理的技术,是把一堆基本相同的请求批量处理。比如,大家同时购买同一个商品,没有必要你买一个我就写一次数据库,完全可以收集到一定数量的请求,一次操作。这个技术可以用作很多方面。比如节省网络带宽,我们都知道网络上的MTU(最大传输单元),以态网是1500字节,光纤可以达到4000多个字节,如果你的一个网络包没有放满这个MTU,那就是在浪费网络带宽,因为网卡的驱动程序只有一块一块地读效率才会高。因此,网络发包时,我们需要收集到足够多的信息后再做网络I/O,这也是一种批量处理的方式。批量处理的敌人是流量低,所以,批量处理的系统一般都会设置上两个阀值,一个是作业量,另一个是timeout,只要有一个条件满足,就会开始提交处理。
所以,只要是异步,一般都会有throttle机制,一般都会有队列来排队,有队列,就会有持久化,而系统一般都会使用批量的方式来处理。

云风同学设计的“排队系统” 就是这个技术。这和电子商务的订单系统很相似,就是说,我的系统收到了你的购票下单请求,但是我还没有真正处理,我的系统会跟据我自己的处理能力来throttle住这些大量的请求,并一点一点地处理。一旦处理完成,我就可以发邮件或短信告诉用户你来可以真正购票了。

在这里,我想通过业务和用户需求方面讨论一下云风同学的这个排队系统,因为其从技术上看似解决了这个问题,但是从业务和用户需求上来说可能还是有一些值得我们去深入思考的地方:

1)队列的DoS攻击。首先,我们思考一下,这个队是个单纯地排队的吗?这样做还不够好,因为这样我们不能杜绝黄牛,而且单纯的ticket_id很容易发生DoS攻击,比如,我发起N个 ticket_id,进入购票流程后,我不买,我就耗你半个小时,很容易我就可以让想买票的人几天都买不到票。有人说,用户应该要用身份证来排队, 这样在购买里就必需要用这个身份证来买,但这也还不能杜绝黄牛排队或是号贩子。因为他们可以注册N个帐号来排队,但就是不买。黄牛这些人这个时候只需要干一个事,把网站搞得正常人不能访问,让用户只能通过他们来买。

2)对列的一致性?对这个队列的操作是不是需要锁?只要有锁,性能一定上不去。试想,100万个人同时要求你来分配位置号,这个队列将会成为性能瓶颈。你一定没有数据库实现得性能好,所以,可能比现在还差

3)队列的等待时间。购票时间半小时够不够?多不多?要是那时用户正好不能上网呢?如果时间短了,用户不够时间操作也会抱怨,如果时间长了,后面在排队的那些人也会抱怨。这个方法可能在实际操作上会有很多问题。另外,半个小时太长了,这完全不现实,我们用15分钟来举例:有1千万用户,每一个时刻只能放进去1万个,这1万个用户需要15分钟完成所有操作,那么,这1千万用户全部处理完,需要1000*15m = 250小时,10天半,火车早开了。(我并非乱说,根据铁道部专家的说明:这几天,平均一天下单100万,所以,处理1000万的用户需要十天。这个计算可能有点简单了,我只是想说,在这样低负载的系统下用排队可能都不能解决问题)

4)队列的分布式。这个排队系统只有一个队列好吗?还不足够好。因为,如果你放进去的可以购票的人如果在买同一个车次的同样的类型的票(比如某动车卧铺),还是等于在抢票,也就是说系统的负载还是会有可能集中到其中某台服务器上。因此,最好的方法是根据用户的需求——提供出发地和目的地,来对用户进行排队。而这样一来,队列也就可以是多个,只要是多个队列,就可以水平扩展了。

我觉得完全可以向网上购物学习。在排队(下单)的时候,收集好用户的信息和想要买的票,并允许用户设置购票的优先级,比如,A车次卧铺买 不到就买 B车次的卧铺,如果还买不到就买硬座等等,然后用户把所需的钱先充值好,接下来就是系统完全自动地异步处理订单。成功不成功都发短信或邮件通知用户。这样,系统不仅可以省去那半个小时的用户交互时间,自动化加快处理,还可以合并相同购票请求的人,进行批处理(减少数据库的操作次数)。这种方法最妙的事是可以知道这些排队用户的需求,不但可以优化用户的队列,把用户分布到不同的队列,还可以像亚马逊的心愿单一样,让铁道部做车次统筹安排和调整(最后,排队系统(下单系统)还是要保存在数据库里的或做持久化,不能只放在内存中,不然机器一down,就等着被骂吧)。

小结

写了那么多,我小结一下:

0)无论你怎么设计,你的系统一定要能容易地水平扩展。也就是说,你的整个数据流中,所有的环节都要能够水平扩展。这样,当你的系统有性能问题时,“加3倍的服务器”才不会被人讥笑。

1)上述的技术不是一朝一夕能搞定的,没有长期的积累,基本无望。我们可以看到,无论你用哪种都会引发一些复杂性。

2)集中式的卖票很难搞定,使用上述的技术可以让订票系统能有几佰倍的性能提升。而在各个省市建分站,分开卖票,是能让现有系统性能有质的提升的最好方法。

3)春运前夕抢票且票量供远小于求这种业务模式是相当变态的,让几千万甚至上亿的人在某个早晨的8点钟同时登录同时抢票的这种业务模式是变态中的变态。业务形态的变态决定了无论他们怎么办干一定会被骂。

4)为了那么一两个星期而搞那么大的系统,而其它时间都在闲着,有些可惜了,这也就是铁路才干得出来这样的事了。

转自:http://coolshell.cn/articles/6470.html#more-6470
作者: linuxtro    时间: 2012-03-08 14:55
平时购票还算顺利
作者: sery    时间: 2012-03-09 12:56
12306 有什么图片呢?回复 74# hb117715785


   
作者: exitgogo    时间: 2012-03-11 12:13
sery 发表于 2012-03-09 12:56
12306 有什么图片呢?回复 74# hb117715785



图片肯定有,不过不是关键问题,呵呵
作者: hbsycw    时间: 2012-03-11 14:21
回复 80# sery

作为一个可扩展的平台架构,独立的文件服务器还是需要的~


   
作者: wangjiafang2    时间: 2012-03-13 10:07
       大数据、海量用户的互联网服务能力、大型网站面对高负载和并发的解决之道,一直以来都是全世界公认的技术难题。有时候,在某些特别时期,即使是一些看似业务逻辑简单的应用在面对突发起来的高负载和高增长的情况下,如何承载住巨大访问量也是一种巨大的挑战。
       12306网站如何扛住元旦、甚至春节高峰期?最新消息12306在全球的Alexa排名已经升至106位,在国内电子商务网站内排名11位,更有新闻报道1月1日-7日的日平均点击高达10亿次。
      在给定系统资源情况下,所能提供的最大请求数,需要做一个特别设计,以防请求数突破极限值。如果没有做特别设计,在极端情况下,吞吐量超过一个点,整个系统将崩溃。而服务架构的目标包括系统高吞吐能力和在极限压力下的稳定输出。为了保证整个系统的稳定性,在设计时需要注意:减小资源分配粒度、主动调度、Flow Control(负载反馈,Throttling、延迟截断)。
     因为12306网站的压力和访问方式在全国电子商务网站中是独一无二的,能在短短几个月的时间站在全球Alex排名106名,这个在世界范围内都是独一无二的;也很难说不是,因为面对网友的质疑:“你们做个系统的性能评估么? 你们做过系统的压力测试么?”,如果是系统化重构的系统,对每个环节面临的新的挑战和压力也会比较清楚,也就不会认为经过了动车组、高铁售票试运行后,就能自然而然地所有车次开放;就不会认为平时正常运行的系统,在元旦、春节全国客流高峰期能够扛住压力。
作者: bear_wangc    时间: 2012-03-13 10:25
本帖最后由 bear_wangc 于 2012-03-13 10:28 编辑


linux架构

1:线路优化
双线联通和电信线路通过智能DNS实现

2:web端部署
分别在联通及电信端加load balance前端可通过lvs4层算法采用sh(源地址散列调度)
lvs分发到后端7层ngx端,可通过ngx来实现七层转发,ngx里面打开proxy_next_upstream功能,可把出现502、500、503、404的错误不显示给用户,直接转发到正常的其它原站服务器,原站具体数目可根据实际负载决定。

3:数据库部署
这种订票系统对数据库的并发非常高,非常需要保证数据库的高可用
主库可使用mysql+heartbeat+drbd两台
从库跑查询及备份,需要6台从库
innodb引擎支持行及锁和事物
可以数据库前端使用memcached多实例,减轻数据库压力





           
作者: king_819    时间: 2012-03-13 16:06
回复 1# 无风之谷


    这个怎么还不开奖,还想弄蚂蚁这本书看看咧!!
作者: 无风之谷    时间: 2012-03-14 14:29
回复 85# king_819


    已经通知蚂蚁评奖了,呵呵,估计这哥们有点儿忙啊。
作者: king_819    时间: 2012-03-14 14:33
回复 86# 无风之谷



     呵呵。。蚂蚁的这本书写的不错,希望能中奖,可以学习下

   
作者: qiuyepiaoling    时间: 2012-03-26 11:41
where 高总
作者: qiuyepiaoling    时间: 2012-03-26 11:44
没看到田总说话嘛
作者: w796933    时间: 2012-03-26 17:46
没什么好谈,   谁去设计 这样的都有这样的问题。   还有  不是用的mysql数据库。  过年  属于特别情况。  
作者: QQ364009738    时间: 2012-03-27 13:49
数据库分库分区,按铁路局,车次,时间

作者: hbsycw    时间: 2012-03-31 12:56
本帖最后由 hbsycw 于 2012-03-31 12:58 编辑

回复 1# 无风之谷

书籍今日已收到,感谢CU, 感谢南非蚂蚁~


   
作者: hbsycw    时间: 2012-09-19 10:50
12306  最新动态,增加了排队系统,可是为什么提交订单后提示要排30多分钟,让人无语~




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2