关于G#F#W和信息自由

每年这段时间都很敏感,今天最突出。过去几年,我的梯子都没有倒过,毕竟自己也就是用来进行技术探索,上上几个top5的网站,从来不在外面乱说话乱起哄,也有自己独立的判断能力,不轻易相信恶意抹黑的花边新闻。但是今年梯子倒了,估计是全面推倒了这次。昨天折腾了一上午终于弄好了,魔高一尺道高一丈,这次启用https加cdn,并且屏蔽一切IP请求主机,应该能撑一段时间。 我理解有些码农们投身G#F#W建设的身不由己,但如果真把这当成伟大事业那就有些悲哀了。要知道,互联网发明最初的目的就是信息分享和信息自由,而我也一直坚信,自由开放下的环境没事的地方,才是真正长治久安。如果有机会,我一定写一部关于码农们和G#F#W之间的你来我往和爱恨纠葛的剧本。

June 6, 2019

CentOS编译安装shadowsocks-libev

部署环境:CentOS 7.4 x64 shadowsocks-libev项目地址 编译安装 yum update -y yum install -y epel-release rng-tools yum install -y git wget gettext gcc autoconf libtool automake make asciidoc xmlto c-ares-devel libev-devel zlib-devel openssl-devel rngd -r /dev/urandom 安装Libsodium export LIBSODIUM_VER=1.0.16 wget https://download.libsodium.org/libsodium/releases/libsodium-$LIBSODIUM_VER.tar.gz tar xvf libsodium-$LIBSODIUM_VER.tar.gz pushd libsodium-$LIBSODIUM_VER ./configure --prefix=/usr && make make install popd ldconfig 安装MbedTLS export MBEDTLS_VER=2.7.0 wget https://tls.mbed.org/download/mbedtls-$MBEDTLS_VER-gpl.tgz tar xvf mbedtls-$MBEDTLS_VER-gpl.tgz pushd mbedtls-$MBEDTLS_VER make SHARED=1 CFLAGS=-fPIC make DESTDIR=/usr install popd ldconfig 安装shadowsocks git clone https://github.com/shadowsocks/shadowsocks-libev.git cd shadowsocks-libev git submodule update --init --recursive ./autogen.sh && ./configure && make make install cd .. 修改配置 mkdir /etc/shadowsocks-libev vi /etc/shadowsocks-libev/config.json 写入以下内容并保存 ...

June 4, 2019

安装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领域驱动设计的理解

一、软件开发首先要回答:要解决什么问题 任何软件系统都不是凭空产生的,而是为了回应某个现实问题。 因此,在开始编码之前,首先需要明确: 系统解决什么问题? 服务哪些用户? 核心价值是什么? 哪些问题属于系统边界,哪些不属于? 系统的定位越清晰,后续设计越容易保持一致。 二、领域(Domain)就是业务问题的范围 DDD强调,软件应该围绕业务本身,而不是围绕数据库或技术框架展开。 所谓领域,可以理解为: 一个具有明确业务目标、业务规则和业务边界的问题空间。 例如: 电商领域关注商品、订单、支付、库存等业务; 社交领域关注用户、关系、内容互动; 金融领域关注账户、交易、风控等。 不同领域拥有不同的核心概念和规则。 三、DDD的核心不是代码,而是模型 DDD认为: 领域模型才是系统真正的核心。 领域模型负责表达: 业务中的重要对象; 对象之间的关系; 业务规则; 状态变化; 生命周期。 代码只是把模型实现出来,而不是直接堆砌业务逻辑。 因此: 领域 → 模型 → 代码 而不是: 数据库 → Controller → SQL 四、真正困难的是理解业务 很多项目失败,并不是因为技术不够,而是因为业务理解不到位。 因此,在建模之前,需要充分理解领域知识,包括: 业务术语 业务规则 使用场景 操作流程 用户真正关心的问题 领域专家、产品经理、开发人员都需要共同参与这一过程。 五、复杂业务需要拆分子领域 大型系统往往不能作为一个整体设计,而需要按照业务职责拆分。 例如一个电商平台可以拆分为: 用户 商品 库存 订单 支付 营销 每个子领域都有自己的职责和边界。 DDD称这种划分为子域(Subdomain)和边界上下文(Bounded Context)。 良好的边界划分能够降低耦合,提高系统演进能力。 六、建模前先梳理四类内容 在设计模型之前,需要把业务整理清楚。 通常包括: 核心概念:有哪些重要业务对象; 业务规则:有哪些必须满足的不变条件; 业务场景:系统需要支持哪些典型操作; 业务流程:这些操作如何串联形成完整业务。 只有把这些内容理顺,模型才有坚实基础。 七、领域模型要服务业务,而不是追求复杂 DDD提供了许多建模工具,例如: ...

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

软件奇才——安德斯·海尔斯伯格(Anders Hejlsberg)

简介 出生于哥本哈根,安德斯·海尔斯伯格曾在丹麦技术大学学习工程,但没有毕业,大学时期他曾替 Nascom microcomputer撰写程式,他曾为Nascom-2电脑撰写蓝标签(Blue Label) Pascal compiler,到了DOS时代他又重新改写这套compiler。当时他在丹麦拥有个叫Poly Data的公司,他编写了Compass Pascal编译器核心,后来叫Poly Pascal。1986年他首次认识了Philippe Kahn。 在Borland公司 安德斯·海尔斯伯格把Compass Pascal编译器核心授权给了美国Borland公司,并作为雇员加入Borland公司,并且是后来所有Turbo Pascal版本与Delphi前3个版本的架构师。Philippe Kahn为第一个版本的Turbo Pascal添加了用户界面与编辑器。 加入微软公司 1996年Hejlsberg加入微软公司。据说,比尔·盖茨亲自参与了这次挖角行动,年薪三百万美金,并许诺安德斯·海尔斯伯格在微软将得到技术上的足够自由和资源支持[1]。据说该事件也是微软公司和Borland公司后续官司的导火索。 在微软公司 进入微软公司后,首先主持了Visual J++的开发工作,后来由于在Java开发工具授权问题上和Sun公司的纠纷,微软停止了Visual J++的后续开发。 这之后,作为.Net概念的发起人之一,安德斯·海尔斯伯格被任命为微软.Net的首席架构师,主持.Net的开发工作。 人物生平 安德斯·海尔斯伯格(Anders Hejlsberg)曾在丹麦科技大学学习工程学。他第一次登上软件界历史舞台是在80年代早期,因为他为MS-DOS和CP/M设计了一个Pascal编译器。当时,还是一个小公司的Borland很快雇用了他,并买下了他的编译器,改称Turbo Pascal。在Borland,Hejlsberg继续开发Turbo Pascal,并最终带领他的小组设计了Turbo Pascal的替代品、开发工具史上的奇迹:Delphi。 1996年,Anders Hejlsberg在Delphi 3发布前离开Borland去了微软(Microsoft)。 在此之前,微软曾多次企图挖走Anders,但都没有成功。据信Anders去微软(主要)不是钱的问题,虽然微软的开价也相当有吸引力: 130万美元年薪外加股票期权和分红,总计超过300万美元。更主要的原因是Anders和Delphi开发组的其他成员在修改编译器的问题上发生了争执;还有,据Borland内部人讲,Anders认为自己不再是“不可缺少的人”。 Anders在Delphi 3中几乎没有做什么工作,Chuck Jazdzewski扮演了一个更重要的角色。(Anders Ohlsson) Anders在Borland时把所有精力都放在了Pascal产品上,也需要新的挑战,这时Bill Gates的亲自邀请,许诺给与挑战的机会,Anders加入了微软就势在必行。 微软用丰厚的薪水、股票认购权和巨额的加盟奖金雇请了 Hejlsberg 之后,Borland 曾提出通过不正当手段吸收新成员的控告。Borland 还曾声称 — 提供了很少的细节来支持指控 — Hejlsberg 正在开发“Delphi for Java”。这场诉讼虽然最终以 Borland 的胜利而收场;但Anders 已经在为微软工作了。 1996年Anders来到微软后,直接主抓Visual J++的研发工作,并在1999年被授予“distinguished engineer”(卓越工程师),在微软仅有16人获得这样的荣誉。 后来微软希望通过开发最新的软件开发语言来赢得软件开发者的拥戴,在微软公司把视窗操作系统和软件向网络迁移的新市场战略中,C#语言是最重要的环节。微软动用了最好的资源。Anders担任了C#语言的首席设计师,同时也是微软.NET战略构架的重要参与决策者。考虑一下Anders的经历,就不会奇怪微软将此重任交给他了。毕竟C#也不是他对软件开发方式重大变革的首次。现在经过几年时间的埋头苦干,C#已成为微软反击Java语言的最有力武器。 业绩与成就 鉴于他为软件开发做出的巨大贡献,Anders在《Dr.Dobb’s》杂志的2001年西部会议上被授予“Prestigious Excellence in Programming Award”,《Dr.Dobb’s》杂志的主编Jonathan Erickson说:“这一荣誉,我们每年只颁给那些在软件开发领域做出非凡贡献的人员,Anders开发的C#和他整个职业生涯中为软件开发所做出的巨大贡献有目共睹,他无愧于这一荣誉!” 社会评价 比尔盖茨也高度评价说:“我们为Anders获得这一荣誉感到无比自豪,Anders在C#创建中所做的努力将会改变现在的软件开发方式,并将在以后的十年继续产生影响。” “程序员是最好的职业”,Anders说:“每两年,CPU的速度要加倍,内存容量是原来的四倍,但是我们的大脑还是原来的大小,很显然,将需要更多的程序员来补充这些。”

August 10, 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