安装shadowsocks的v2ray插件

服务端部署 部署环境:CentOS 7.6 x64 安装Shadowsocks-libev 这个之前博文说过,就不重复了。 安装v2ray-plugin 我懒得编译,直接下载已经编译好的了,解压到/usr/local/bin/下。 获取SSL证书 我使用的是Let’s Encrypt的免费证书(这里建议使用CloudFlare的免费证书),执行命令之前记得先将域名的A记录解析到服务器IP上,并且开放80和443端口。 wget https://dl.eff.org/certbot-auto chmod a+x certbot-auto ./certbot-auto certonly 成功之后会有/etc/letsencrypt/live/域名/fullchain.pem和/etc/letsencrypt/live/域名/privkey.pem两个文件。 修改配置文件 默认配置文件在/etc/shadowsocks-libev/config.json,如下文所示,在最后加上plugin和plugin_opts,把域名换成自己的就行。这里采用的是Shadowsocks over websocket (HTTPS),其它的可以自己参考GitHub上的介绍。 { "server":"0.0.0.0", "server_port":443, "local_port":1080, "password":"password", "timeout":300, "method":"aes-256-gcm", "plugin":"v2ray-plugin", "plugin_opts":"server;tls;cert=/etc/letsencrypt/live/域名/fullchain.pem;key=/etc/letsencrypt/live/域名/privkey.pem;host=域名;loglevel=none" } 最后执行ss-server -c /etc/shadowsocks-libev/config.json -f /run/shadowsocks.pid即可。 客户端设置 先安装对应平台的Shadowsocks客户端。 Windows 直接下载已经编译好的v2ray-plugin的windows版,解压后命名为v2ray-plugin.exe和Shadowsocks.exe放在同一文件夹下。 在Shadowsocks的服务器设置中,插件程序填v2ray-plugin,插件选项填tls;host=域名。域名要和服务端设置的一致。 Android 安装v2ray-plugin-android,打开Shadowsocks编辑服务器,在最下面的插件中选择v2ray,配置Transport mode为websocket-tls,Hostname为服务端设置的域名即可。 Ubuntu 直接下载已经编译好的v2ray-plugin,解压到/usr/local/bin/下。 编辑配置文件/etc/shadowsocks-libev/config.json,如下文所示,在最后加上plugin和plugin_opts,域名要和服务端设置的一致。 { "server":"域名", "server_port":443, "local_port":1080, "password":"password", "timeout":300, "method":"aes-256-gcm", "plugin":"v2ray-plugin", "plugin_opts":"tls;host=域名;loglevel=none" } 最后执行ss-local -c /etc/shadowsocks-libev/config.json即可。 优势 你甚至可以把SS服务器放在CDN后面,免费的CDN有Cloudflare。 然后,最重要的,让你的服务器屏蔽所有除了CloudFlare和你自己的IP之外的所有IP。 基本上很长一段时间内,G#F#W就拿你没办法了。 原文: https://blog.m3chd09.com/2019/02/01/v2ray-plugin-for-shadowsocks.html

June 4, 2019

【转】浅谈我对DDD领域驱动设计的理解

遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决。 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品。所以,自然而然就想到要做一个普通电商系统,用于实现在线销售自己企业产品的目的。 再比如,我是一家互联网公司,公司有很多系统对外提供服务,面向很多客户端设备。但是最近由于各种原因,导致服务经常出故障。所以,我们希望通过各种措施提高服务的质量和稳定性。其中的一个措施就是希望能做一个灰度发布的平台,这个平台可以提供灰度发布的服务。然后,当某个业务系统做了一些修改并需要发布时,可以使用我们的灰度发布平台来非常方便的实现灰度发布的功能。比如在灰度发布平台上方便的定制允许哪些特定的客户端才会访问新服务,哪些客户端继续使用老服务。灰度发布平台可以提供各种灰度的策略。有了这样的灰度发布机制,那即便系统的新逻辑有什么问题,受影响的面也不会很大,在可控范围内。所以,如果公司里的所有对外提供服务的系统都接入了灰度平台,那这些系统的发布环节就可以更加有保障了。 总之,我们做任何一个软件系统,都是有原因的,否则就没必要做这个系统,而这个原因就是我们遇到的问题。所以,通过问题,我们就知道了我们需要一个什么样的系统,这个系统解决什么样的问题。最后,我们就很自然的得出了一个目标,即知道了自己要什么。比如我要做一个论坛、一个博客系统、一个电商平台、一个灰度发布系统、一个IDE、一个分布式消息队列、一个通信框架,等等。 DDD切入点1 - 理解概念 DDD的全称为Domain-driven Design,即领域驱动设计。下面我从领域、问题域、领域模型、设计、驱动这几个词语的含义和联系的角度去阐述DDD是如何融入到我们平时的软件开发初期阶段的。要理解什么是领域驱动设计,首先要理解什么是领域,什么是设计,还有驱动是什么意思,什么驱动什么。 一、什么是领域(Domain)? 前面我们已经清楚的知道我们现在要做一个什么样的系统,这个系统需要解决什么问题。我认为任何一个系统都会属于某个特定的领域,比如论坛是一个领域,只要你想做一个论坛,那这个论坛的核心业务是确定的,比如都有用户发帖、回帖等核心基本功能。比如电商平台、普通电商系统,这种都属于网上电商领域,只要是这个领域的系统,那都有商品浏览、购物车、下单、减库存、付款交易等核心环节。所以,同一个领域的系统都具有相同的核心业务,因为他们要解决的问题的本质是类似的。 因此,我们可以推断出,一个领域本质上可以理解为就是一个问题域,只要是同一个领域,那问题域就相同。所以,只要我们确定了系统所属的领域,那这个系统的核心业务,即要解决的关键问题、问题的范围边界就基本确定了。通常我们说,要成为一个领域的专家,必须要在这个领域深入研究很多年才行。因为只有你研究了很多年,你才会遇到非常多的该领域的问题,同时你解决这个领域中的问题的经验也非常丰富。很多时候,领域专家比技术专家更加吃香,比如金融领域的专家。 二、什么是设计(Design)? DDD中的设计主要指领域模型的设计。为什么是领域模型的设计而不是架构设计或其他的什么设计呢?因为DDD是一种基于模型驱动开发的软件开发思想,强调领域模型是整个系统的核心,领域模型也是整个系统的核心价值所在。每一个领域,都有一个对应的领域模型,领域模型能够很好的帮我们解决复杂的业务问题。 从领域和代码实现的角度来理解,领域模型绑定了领域和代码实现,确保了最终的代码实现就一定是解决了领域中的核心问题的。因为:1)领域驱动领域模型设计;2)领域模型驱动代码实现。我们只要保证领域模型的设计是正确的,就能确定领域模型可以解决领域中的核心问题;同理,我们只要保证代码实现是严格按照领域模型的意图来落地的,那就能保证最后出来的代码能够解决领域的核心问题的。这个思路,和传统的分析、设计、编码这几个阶段被割裂(并且每个阶段的产物也不同)的软件开发方法学形成鲜明的对比。 三、什么是驱动(Driven)? 上面其实已经提到了,就是:1)领域驱动领域模型设计;2)领域模型驱动代码实现。这个就和我们传统的数据库驱动开发的思路形成对比了。DDD中,我们总是以领域为边界,分析领域中的核心问题(核心关注点),然后设计对应的领域模型,再通过领域模型驱动代码实现。而像数据库设计、持久化技术等这些都不是DDD的核心,而是外围的东西。 领域驱动设计(DDD)告诉我们的最大价值我觉得是:当我们要开发一个系统时,应该尽量先把领域模型想清楚,然后再开始动手编码,这样的系统后期才会很好维护。但是,很多项目(尤其是互联网项目,为了赶工)都是一开始模型没想清楚,一上来就开始建表写代码,代码写的非常冗余,完全是过程是的思考方式,最后导致系统非常难以维护。而且更糟糕的是,出来混总是要还的,前期的领域模型设计的不好,不够抽象,如果你的系统会长期需要维护和适应业务变化,那后面你一定会遇到各种问题维护上的困难,比如数据结构设计不合理,代码到处冗余,改BUG到处引入新的BUG,新人对这种代码上手困难,等。而那时如果你再想重构模型,那要付出的代价会比一开始重新开发还要大,因为你还要考虑兼容历史的数据,数据迁移,如何平滑发布等各种头疼的问题。所以,就导致我们最后天天加班。 虽然,我们都知道这个道理,但是我也明白,人的习惯很难改变的,大部分人都很难从面向过程式的想到哪里写到哪里的思想转变为基于系统化的模型驱动的思维。我想,这或许是DDD很难在中国或国外流行起来的原因吧。但是,我想这不应该成为我们放弃学习DDD的原因,对吧! 概念总结: 领域就是问题域,有边界,领域中有很多问题; 任何一个系统要解决的那个大问题都对应一个领域; 通过建立领域模型来解决领域中的核心问题,模型驱动的思想; 领域建模的目标针对我们在领域中所关心的问题,即只针对核心关注点,而不是整个领域中的所有问题; 领域模型在设计时应考虑一定的抽象性、通用性,以及复用价值; 通过领域模型驱动代码的实现,确保代码让领域模型落地,代码最终能解决问题; 领域模型是系统的核心,是领域内的业务的直接沉淀,具有非常大的业务价值; 技术架构设计或数据存储等是在领域模型的外围,帮助领域模型进行落地。 DDD切入点2 - 理解领域、拆分领域、细化领域 一、理解领域知识是基础 上面我们通过第一步,虽然我们明确了要做一个什么样的系统,该系统主要解决什么问题,但是就这样我们还无法开始进行实际的需求分析和模型设计,我们还必须将我们的问题进行拆分,需求进行细化。有些时候,需求方,即提出问题的人,很可能自己不清楚具体想要什么。他只知道一个概念,一个大的目标。比如他只知道要做一个股票交易系统,一个灰度发布系统,一个电商平台,一个开发工具,等。但是他不清楚这些系统应该具体做成什么样子。这个时候,我认为领域专家就非常重要了,DDD也非常强调领域专家的重要性。因为领域专家对这个领域非常了解,对领域内的各种业务场景和各种业务规则也非常清楚,总之,对这个领域内的一切业务相关的知识都非常了解。所以,他们自然就有能力表达出系统该做成什么样子。所以,要知道一个系统到底该做成什么样子,到底哪些是核心业务关注点,只能靠沉淀领域内的各种知识,别无他法。因此,假设你现在打算做一个电商平台,但是你对这个领域没什么了解,那你一定得先去了解下该领域内主流的电商平台,比如淘宝、天猫、京东、亚马逊等。这个了解的过程就是你沉淀领域知识的过程。如果你不了解,就算你领域建模的能力再强,各种技术架构能力再强也是使不上力。领域专家不是某个固定的角色,而是某一类人,这类人对这个领域非常了解。比如,一个开发人员也可以是一个领域专家。假设你在一个公司开发和维护一个系统已经好几年了,但是这个系统的产品经理(PD)可能已经换过好几任了,这种情况下,我相信这几任产品经理都没有比你更熟悉这个领域。 二、拆分领域 上面我们明白了,领域建模的基础是要先理解领域,让自己成为领域专家。如果做到了这点,我们就打好了坚实的基础了。但是,有时一个领域往往太复杂,涉及到的领域概念、业务规则、交互流程太多,导致我们没办法直接针对这个大的领域进行领域建模。所以,我们需要将领域进行拆分,本质上就是把大问题拆分为小问题,然后各个击破的思路。然后既然把一个大的领域划分为了多个小的领域(子域),那最关键的就是要理清每个子域的边界;然后要搞清楚哪些子域是核心子域,哪些是非核心子域,哪些是公共支撑子域;然后,还要思考子域之间的联系是什么。那么,我们该如何划分子域呢?我的个人看法是从业务相关性的角度去思考,也就是我们平时说的按业务功能为出发点进行划分。还是拿经典的电商系统来分析,通常一个电商系统都会包含好几个大块,比如: 会员中心:负责用户账号登录、用户信息的管理; 商品中心:负责商品的展示、导航、维护; 订单中心:负责订单的生成和生命周期管理; 交易中心:负责交易相关的业务; 库存中心:负责维护商品的库存; 促销中心:负责各种促销活动的支持; 上面这些中心看起来很自然,因为大家对电子商务的这个领域都已经非常熟悉了,所以都没什么疑问,好像很自然的样子。所以,领域划分是不是就是没什么挑战了呢?显然不是。之所以我们觉得子域划分很简单,是因为我们对整个大领域非常了解了。如果我们遇到一个冷门的领域,就没办法这么容易的去划分子域了。这就需要我们先去努力理解领域内的知识。所以,我个人从来不相信什么子域划分的技巧什么的东西,因为我觉得这个工作没有任何诀窍可以使用。当我们不了解一个东西的时候,如何去拆解它?当我们对整个领域有一定的熟悉了,了解了领域内的相关业务的本质和关系,我们就自然而然的能划分出合理的子域了。不过并不是所有的系统都需要划分子域的,有些系统只是解决一个小问题,这个问题不复杂,可能只有一两个核心概念。所以,这种系统完全不需要再划分子域。但不是绝对的,当一个领域,我们的关注点越来越多,每个关注点我们关注的信息越来越多的时候,我们会不由自主的去进一步的划分子域。比如,也许我们一开始将商品和商品的库存都放在商品中心里,但是后来由于库存的维护越来越复杂,导致揉在一起对我们的系统维护带来一定的困难时,我们就会考虑将两者进行拆分,这个就是所谓的业务垂直分割。 三、细化子域 通过上面的两步,我们了解了领域里的知识,也对领域进行了子域划分。但这样还不够,凭这些我们还无法进行后续的领域模型设计。我们还必须再进一步细化每个子域,进一步明确每个子域的核心关注点,即需求细化。我觉得我们需要细化的方面有以下几点: 梳理领域概念:梳理出领域内我们关注的概念、概念的关系,并统一交流词汇,形成统一语言; 梳理业务规则:梳理出领域内我们关注的各种业务规则,DDD中叫不变性(invariants),比如唯一性规则,余额不能小于零等; 梳理业务场景:梳理出领域内的核心业务场景,比如电商平台中的加入购物车、提交订单、发起付款等核心业务场景; 梳理业务流程:梳理出领域内的关键业务流程,比如订单处理流程,退款流程等; 从上面这4个方面,我们从领域概念、业务规则、交互场景、业务流程等维度梳理了我们到底要什么,整理了整个系统应该具备的功能。这个工作我觉得是一个非常具有创造性和有难度的工作。我们一方面会主观的定义我们想要什么;另一方面,我们还会思考我们要的东西的合理性。我认为这个就是产品经理的工作,产品经理必须要负起职责,把他的产品充分设计好,从各个方面去考虑,如何设计一个产品,才能更好的解决用户的核心诉求,即领域内的核心问题。如果对领域不够了解,如果想不清楚用户到底要什么,如果思考问题不够全面,谈何设计出一个合理的产品呢? 关于领域概念的梳理,我觉得可以采用四色原型分析法,这个分析法通过系统的方法,将概念划分为不同的种类,为不同种类的概念标注不同的颜色。然后将这些概念有机的组合起来,从而让我们可以清晰的分析出概念和概念之间的关系。有兴趣的同学可以在网上搜索下四色原型。 注意:上面我说的这四点,重点是梳理出我们要什么功能,而不是思考如何实现这些功能,如何实现是软件设计人员的职责。 DDD切入点3 - 领域模型设计 这部分内容,我想学习DDD的人都很熟悉了。DDD原著中提出了很多实用的建模工具:聚合、实体、值对象、工厂、仓储、领域服务、领域事件。我们可以使用这些工具,来设计每一个子域的领域模型。最终通过领域模型图将设计沉淀下来。要使用这些工具,首先就要理解每个工具的含义和使用场景。不要以为很简单哦,比如聚合的划分就是一个非常具有艺术的活。同一个系统,不同的人设计出来的聚合是完全不同的。而且很有可能高手之间的最后设计出来的差别反而更大,实际上我认为是世界观的相互碰撞,呵呵。所以,要领域建模,我觉得每个人都应该去学学哲学知识,这有助于我们更好的认识世界,更好的理解事物的本质。 关于这些建模工具的概念和如何运用我就不多展开了,我博客里也有很多这方面的介绍。下面我再讲一下我认为比较重要的东西,比如到底该如何领域建模?步骤应该是怎么样的? 一、领域建模的方法 通过上面我介绍的细化子域的内容,现在再来谈该如何领域建模,我觉得就方便很多了。我的主要方法是: 划分好边界上下文,通常每个子域(sub domain)对应一个边界上下文(bounded context),同一个边界上下文中的概念是明确的,没有任何歧义; 在每个边界上下文中设计领域模型,具体的领域模型设计方法有很多种,如以场景为出发点的四色原型分析法,或者我早期写的这篇文章;这个步骤最核心的就是找出聚合根,并找出每个聚合根包含的信息;关于如何设计聚合,可以看一下我写的这篇文章; 画出领域模型图,圈出每个模型中的聚合边界; 设计领域模型时,要考虑该领域模型是否满足业务规则,同时还要综合考虑技术实现等问题,比如并发问题;领域模型不是概念模型,概念模型不关注技术实现,领域模型关心;所以领域模型才能直接指导编码实现; 思考领域模型是如何在业务场景中发挥作用的,以及是如何参与到业务流程的每个环节的; 场景走查,确认领域模型是否能满足领域中的业务场景和业务流程; 模型持续重构、完善、精炼; 二、领域模型的核心作用: 抽象了领域内的核心概念,并建立概念之间的关系; 领域模型承担了领域内的状态的维护; 领域模型维护了领域内的数据之间的业务规则,数据一致性; 需要特别注意的是,领域模型设计只是整个软件设计中的很小一部分。除了领域模型设计之外,要落地一个系统,我们还有非常多的其他设计要做,比如: ...

March 6, 2019

互联网架构启示:一根网线引发的“血案”

互联网架构启示:一根网线引发的“血案” 引言:当一个网站做大的时候,无论是研发还是运维,每一个细节都至关重要,网站的任何一个小的瑕疵都会被无限放大。 公司有一个基于微信公共服务器号开发的产品,主要为微信用户提供在线交流、互动、阅读和科研分析等功能。前阵子升级了支付接口,运营人员开始用红包推广,并且把原来微信服务号的积累的用户引流到服务号本身的网站服务,网站堵塞时秒并发连接数峰值达到1k,数据库瞬间批处理数也达到了2k+,这个量其实不算什么,但因为运维架构的一个疏忽,导致网站2次宕机。这里先说明两点:运维属于公司另外一个部门,当然大家还是相互协作还算比较好;我们的服务器都是32G内存,4核2GHz的CPU的品牌服务器。 第一次宕机:抢红包导致宕机3小时。 我们发布完毕2.0版本之后,运营很开心,打算搞一次庆祝活动:只要来关注公共号,进入首页就可以另一个1块钱红包,任何人都可以。发红包当天,我没有接到通知,到家收到微信的提醒,过了差不多1小时,运营电话过来说网站慢了,而此时我连服务器都很难连接不上,运维的说50兆的带宽只用了8兆(这里有一个细节他没有告诉我:网络是一条几乎是直线在运行),再过来半小时,网站几乎打不开了。过了一阵子我登录终于能登录服务器了,但还是很卡,看了服务器的指标,我关注了io、cpu和内存,发现全部正常,idle很高,几乎都是80%,不过没有注意网络。接着两个多小时,直到红包抢完,网站才开始能正常访问。第二天,运维与我们完成了负载均衡的搭建,4台web,1台专用db,cache不变,与架构变化之前一样,只做了web服务器级别的cache,我个人判断这样的量还不需要加memcached和读写分离。后面两次发红包量没有那么大,服务器都正常,但我观察了服务器,发现一个现象:当并发数比较多的时候,db服务器指标还是正常,但总有点卡顿,这次我观察到有时候内外的网络会瞬间冲到98MB,咨询运维的同事说这个正常我们内网有千兆网卡呢,而且现在外网的流量不到占用不到10%。 第二次宕机:活动导入流量导致宕机1小时。 这一次宕机,我觉得不可能发生的。当天傍晚,运营的人一下子给微信十万级别的用户发消息,把他们引流进入网站,过了1小时网站又宕机了,一直过了高峰才恢复,那天只有运维的人在跟服务器情况。第二天,运维的跟我说是我们数据库有问题,他们的理由是:外网流量还是一条7MB直线,所有服务器的指标都正常,但是一拔数据库的网线整个网际通了,所以是db处理不过来那么多请求、或者代码有问题。我当时有点懵了,因为看了流量,那天2个小时的pv达到了10w,鉴于这个产品我们使用了比较新的开发框架,我开始怀疑代码问题、数据库连接问题等等。然后先把所有能优化的都优化,包括动态的内容等也加cache,上了1台memcached服务器。我们还把用户行为用消息队列进行异步处理。改完之后开始google,研究程序架构支撑情况、数据库并发数等等,结论是感觉昨晚的量在昨晚这种条件下网站不应该宕机的,我甚至都怀疑是不是服务器采购的时候被动手脚了-_- 过了一周运营再次搞活动,活动之前我还发现一个问题:个别图书封面居然有5mb的图片,原来产品经理为了让用户看清楚图书封面要求用原图,我赶紧让工程师改成压缩图片。晚上刚到家不久,运营电话又过来了,说虽然没有宕机,内容也能看,但还是有点慢。我接到电话觉得很不可思议,心里想怎么流量那么高。登录服务器之后,发现流量也就是和上次一样,症状和上次也是一样,和运维的沟通,说他连不上服务器(网络是正常的),我特地看了db的连接也只有2位数,虽然偶尔会突然到2k多,但我知道这是因为网络堵住连接不到memcached。当天晚上就咨询以前的认识的运维大拿们,他们也觉得很不可思议,但我们判断肯定是硬件架构哪里出了问题,我把服务器的指标等都截图保留。公司运维的哥们这时候说怀疑是内外网公用网卡的原因,不过这种做法也不是不可以,因为内网有千兆网卡。第二天,又咨询了很多人,大家的结论是:网络有问题。问了好几次公司运维,都说:交换机是千兆的、防火墙是千兆的、网卡是千兆的,后来我以前的同事乌咔咔大拿注意到我截图里面显示网卡只有100MB,我赶紧检查所有的服务器,发现:内外网公用一个只有100MB的网卡!!!问了运维,他说网卡肯定是千兆,我说是不是被自适应了,他楞了一下,说不是自适应,是网线可能是百兆的,去机房确认了一下,发现服务器用的全是5类网线,而且是自己做的……运维也知道是啥原因了,走了特批买了超6类的网线换上。 目前网站一切正常,未来如果突破一定的用户量,肯定要做db的读写分离、cdn等。回过头来看,第一次宕机的可能性很多种,网线问题、web服务器超并发问题、db和web在同一台问题等;第二次宕机的原因应该是:这根网线引发,内网网络瞬间被挤爆,所有内部通信在等待、数据库连接超时,我的理由是这一天的秒连接数也只有几百,数据库连接也就1k多;第三次虽然没有宕机,但网站有些慢,依然是因为这根网线的原因。 这就是一根网线引发的“血案”的案例,希望对看到的工程师们有所帮助。我本人一直做开发,也自认为自己开发能力、软件系统架构能力很强,但之前确实忽略了硬件方面的知识,这一次是彻彻底底、从头到尾上了一个课。

August 13, 2015

Memcached简介及相关访问客户端

 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。 Memcached:是守护程序,也就是服务端,它与分布式无关,它的下载地址是http://memcached.org/; Memcached的客户端:客户端是指通过各种语言(php、java、.net)访问Memcached服务端,客户端实现了分布式算法,这里需要注意,php有两个访问memcahced的客户端 php其中一个客户端是:memcache(下载地址:http://php.net/manual/en/book.memcache.php),直接使用这个客户端的memcache.so或者memcache.dll文件就可以连接到Memcached服务端,不需要额外的其他组件,不过这个客户端的功能比较差,不支持CAS操作等; php另外一个客户端是:memcached(下载地址:http://php.net/manual/en/book.memcached.php),使用这个客户端,需要在客户端上安装libmemcached(下载地址:http://libmemcached.org/libMemcached.html)客户端,然后再引用memcached.so或者memcached.dll,这个客户端支持大量的操作,而且也非常稳定,建议使用这个客户端。

October 22, 2012

ios客户端开发使用框架

这个月开始重启ios客户端的研发,之前做过一个图书软件,这次要做一个学术在线的客户端。 这次用到了如下一些框架: FMDB:一款轻量级的访问sqllite类库,非常强大 ,FMDB将SQLite API进行了很友好的封装,使用上非常方便,对于那些使用纯Sqlite API来进行数据库操作的app,可以考虑将其迁移到基于FMDB上,这对于以后数据库相关功能的开发维护,可以提高不少效率。 ASIHTTPRequest:一款访问网络的类库,支持断点续传。 ASIHTTPRequest就是一个对CFNetwork API进行了封装,并且使用起来非常简单的一套API,用Objective-C编写,可以很好的应用在Mac OS X系统和iOS平台的应用程序中。ASIHTTPRequest适用于基本的HTTP请求,和基于REST的服务之间的交互。 **cocoa-aes:**一款进行进行aes加密解密的类库,我自己做了封装,支持aes的128对称加密算法。

August 12, 2012

面向对象必知:继承本质论

每个人开始学习面向对象的时候,基本上都感觉自己很能理解什么是“继承”,可是我相信没有多少个人是真正地理解了“继承的本质”。 继承,就是面向对象中的类与类直接的关系,继承的类叫做子类或者派生类,而被继承的泪叫做父类、基类或者超类。通过继承,子类可以拥有父类的属性、方法,同时子类也可以添加新的属性或者方法,还可以修改父类的方法和属性等。 在《你必须知道的.NET》中,作者列举了下面几个关于继承的要点: 1、继承是可以传递的,子类是对父类的扩展,必须继承父类方法,同时可以添加新方法; 2、子类可以调用父类的方法、属性和字段,但是父类不能够调用子类的方法、属性和字段; 3、虚方法如何实现覆写操作,使得父类指针可以指向子类对象成员; 4、子类不仅继承了父类公共成员,也继承了私有成员,只是在子类中不被访问; 5、new在虚方法继承中起阻断作用。 上面这五条几乎可以说是继承的本质,深刻理解了这些,基本可以说对继承掌握了,不过还有一个比较重要的地方需要注意,请看: #region 深入理解继承机制、多态、封装 public abstract class Animal { public abstract void ShowType(); public void Eat() { Console.WriteLine(“All Animals need eating!”); } } public class Bird : Animal { private string type = “Bird”; public override void ShowType() { Console.WriteLine(“Type is {0}”, type); } private string color; public string Color { get { return this.color; } set { this.color = value; } } } public class Chicken : Bird { private string type = “Chicken”; public override void ShowType() { Console.WriteLine(“Type is {0}”, type); } public void ShowColor() { Console.WriteLine(“Color is {0}”, Color); } } #endregion 上面是定义了一个抽象父类和两个子类,下面是调用方法: #region 深入理解OO思想 //Bird bird 创建的是一个Bird类型的引用,而new Bird()完成的是创建Bird对象,分配内存空间和初始化操作 Bird bird = new Bird(); Chicken chicken = new Chicken(); Bird bird2 = new Chicken();//请注意上面这里的区别 bird.ShowType(); chicken.ShowType(); bird2.ShowType(); #endregion 如果你能够了解为什么上面得到的结果,你就深刻理解了什么是继承了

May 21, 2012

面向对象必知:深入理解对象

上一节讲到了类,这次讲对象。一个类可以创建对象,对象可以操作类里面的方法,也可以操作类从父类继承的合法方法,还可以操作其他类的共用方法。 在程序设计(这里都以C#语言为准)中的对象和人类世界中的是类似的,人类世界中每一个人都是一个对象,一个人有自己的姓名、身高等属性,一个人可以做很多事情,也受到很多约束;而程序设计里的对象就是模拟了人类世界的对象,一个对象必须要创建,这个对象在创建之时就确定了它的属性,这个对象可以有很多方法,这个对象受到访问权限的约束。 人类生活在人类社会这个时间里,而对象生存在.NET中的CLR环境;人类在社会里受到法律、风俗等约束,对象在CLR里也同样有着自己的一套约定,比如类型、语法等。 对象最为重要的是:有自己的属性(有如一个人的属性)、有自己可以访问的方法(有如一个人可以做的事情)、访问权限(有如一个人做什么事情受到的权限限制)。

May 21, 2011

面向对象程序设计必知:深入理解类

人以类聚”,这个成语说明了类的概念,在面向对象设计中的类也是如此,一个类是一组东西的抽象,类可以有抽象出来的类(抽象类),也可以是具体的类,抽象类往往都有具体类,具体类负责实现抽象类定义的方法。一个类,里面定义了属于这个类别的东西共同拥有的属性和方法,比如Duck鸭子类,里面有叫声,羽毛等鸭子都有的属性,有游泳,叫等鸭子都有的方法。 在C#里类还分静态类和非静态类,最大的区别是静态类里必须都是静态方法,静态类必须用类名去访问里面的方法,静态类是编译时就确定的;非静态类必须先创建一个实例对象,然后才能去访问类里的成员和方法,非静态类是动态绑定的,也就是在执行的时候才确定要执行什么方法。 类有修饰它的关键字:Public、Protected,Private。这几个关键字代表的意思是: 1、Public:公共的类,这个类可以在外面的类被访问到; 2、Protected:私有的类,这个类可以在继承它的类被访问到; 3、Private:私有的类,这个类不能在任何其他外面的被类访问到。

May 21, 2010

什么叫设计模式

现在网上有大量的文章写设计模式,无论是Gof的23种设计模式,还是其他自己创造处理的模式,但是在做这些工作之前应该深入理解什么叫设计模式。 总的来说,设计模式是一各个编程套路,类似于建筑设计,网上也有关于什么叫设计模式的经典分析,下面仅仅作为摘要简述: 1、来自豆瓣网的声音: 设计模式并不是什么新的东西。有些模式,你或许已经在实际项目中应用了很多年了,只是不知道人家原来是这么称呼它的! 2、来自博客园的分析: 设计模式就是解决问题的一种方式,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就可以一次又一次的使用该解决方案而不做重复性的劳动。设计模式有四个基本要素:模式名称、问题、解决方案、效果。 按照模式的目的性准则,模式可以分为创建型模式、结构型模式和行为型模式。创建型模式与对象的创建有关;结构型模式处理类和对象的组合;行为型模式对类和对象怎样交互和怎样分配职责进行描述。 按照模式的范围准则,模式可以分为类模式和对象模式。类模式处理类和子类的关系,这些关系通过继承建立,是静态的,在编译时就确定下来。对象模式是处理对象之间的关系,这些关系在运行时刻是可以变化的,更具动态性。 创建型类模式将对象的创建工作部分延迟到子类。创建型对象模式则是将它延迟到另一个对象中。 结构型类模式使用继承机制来组合类。结构型对象模式则描述了对象的组装方式。 行为型类模式使用继承描述算法和控制流。行为型对象模式描述使用一组对象怎样协作完成单个对象无法完成的任务。

May 21, 2009

关于Web性能分析和大型网站架构设计

对于网站的理解,不同层次的人有不同的理解。一个网站可以简单地只有几个静态页面,花上一两个小时的时间就可以做好;但是也可能设计地非常精巧,能够承受亿万级的访问量,这样的网站设计起来就很复杂,而且会耗掉大量的人力物力。简单的网站提供的功能是有限的,作用也很小;但是对于大型的网站,就非常地有用,可以提供丰富多彩的功能,比如Google、百度、淘宝、新浪、搜狐等这些网站。 所有的网站开发人员都希望能够设计出性能稳定、负载能力大的网站,而一个对于web系统:最大的瓶颈是数据库;展现效率的决定性因素是前端调用和架构;系统健壮性的决定性因素是总体架构。 1、Web系统最大瓶颈是数据库 无论是使用哪类数据库管理软件(DB2、SQL Server、Oracle),数据库瓶颈是让网站开发者最为头痛的,每一次数据库连接操作都会消耗极大的系统资源(CPU资源、磁盘IO资源等),如果并发达到百万级,没有合理的数据库访问策略,那么网站肯定马上就瘫痪。解决这一问题,主要靠缓存机制,而在数据库缓存里最好用的莫过于Memcached(非常高效的分布式数据库缓存工具),有了Memcached,那么就可以大量地减少数据库链接数,而且可以进行分布式,极大了减小了数据库的压力,而且可以随时增加服务器扩充数据库负载能力。当然Memcached并非绝对灵丹妙药,必须在网站架构和程序代码上下功夫,比如数据库读写分离、缓存更新机制等。Memcached是针对Linux操作系统的,在Windows下也可以用,但并不一定能够达到很好的效果,幸运的是微软现在也自己开发了一套类似的东西:Velocity。 2、展现效率的决定性因素是前端调用和架构 如果你认真去分析淘宝网的页面代码,你就会发现这句话一点都没有错,当服务器响应快速了之后,如何能够展现地更快,就是前端优化,淘宝的前端开发工程师曾说过:页面响应80%时间来自js、css和html代码,由此可见前端的重要性。对于css和div,在兼容浏览器的前提下,最好能够尽量向web标准靠拢,对于js,我建议是使用稳定的js框架,个人喜欢JQuery。 3、系统健壮性的决定性因素是总体架构 网站的总体架构相当于一个人的骨架,没有好的架构不用提稳定性了。一个好的网站架构应该满足:三层(表现、逻辑、数据访问)分离、代码规范、可扩充,如果是大型网站,还要是分布式的、数据库读写分离。

May 21, 2009