Tuesday, December 15, 2015

Architecture Misc



http://martinfowler.com/bliki/SacrificialArchitecture.html
http://www.infoq.com/cn/news/2014/11/sacrificial-architecture
But often the best code you can write now is code you'll discard in a couple of years time.
At Google, the explicit rule is to design a system for ten times its current needs, with the implication that if the needs exceed an order of magnitude then it's often better to throw away and replace from scratch[1]. It's common for subsystems to be redesigned and thrown away every few years.

Good modularity is a vital part of a healthy code base, and modularity is usually a big help when replacing a system. Indeed one of the best things to do with an early version of a system is to explore what the best modular structure should be so that you can build on that knowledge for the replacement. While it can be reasonable to sacrifice an entire system in its early days, as a system grows it's more effective to sacrifice individual modules - which you can only do if you have good module boundaries.


You can also apply this principle to features within an existing system. If you're building a new feature it's often wise to make it available to only a subset of your users, so you can get feedback on whether it's a good idea. To do that you may initially build it in a sacrificial way, so that you don't invest the full effort on a feature that you find isn't worth full deployment.
Modular replaceability is a principal argument in favor of a microservices architecture, but I'm wary to recommend that for a sacrificial architecture. Microservices imply distribution and asynchrony, which are both complexity boosters. I've already run into a couple of projects that took the microservice path without really needing to — seriously slowing down their feature pipeline as a result. So a monolith is often a good sacrificial architecture, with microservices introduced later to gradually pull it apart.
谷歌的高级研究员Jeff Dean在他的陈述中提到,在代码库太旧之前就重新设计或者抛弃掉。
当前正确的设计对于十倍或者百倍的增长可能就是非常错误的了,可以针对十倍的增长进行设计,但在增长到百倍之前就要计划去重写了。
Justin Meyer是jQuery顾问和JavaScriptMVCCanJSjQueryPP的联合创始人,他在近期的博客中分享了模块化的重要性,他说:
模块化是一个可维护性应用最重要的特性。一个模块化的应用不会浪费,部件可以被修改、替换或者抛弃掉,而不会影响到应用的其他部件。



http://ifeve.com/talk-arch-module/
如何划分模块?
  • 基于水平切分。把一个系统按照业务类型进行水平切分成多个模块,比如权限管理模块,用户管理模块,各种业务模块等。
  • 基于垂直切分。把一个系统按照系统层次进行垂直切分成多个模块,如DAO层,SERVICE层,业务逻辑层。
  • 基于单一职责。将代码按照职责抽象出来形成一个一个的模块。将系统中同一职责的代码放在一个模块里。比如我们开发的系统要对接多个渠道的数据,每个渠道的对接方式和数据解析方式不一样,为避免不同渠道代码的相互影响,我们把各个渠道的代码放在各自的模块里。
  • 基于易变和不易变。将不易变的代码抽象到一个模块里,比如系统的比较通用的功能。将易变的代码放在另外一个或多个模块里,比如业务逻辑。因为易变的代码经常修改,会很不稳定,分开之后易变代码在修改时候,不会将BUG传染给不变的代码。

易变和不易变?

根据代码的易变程度,将不变和变化的功能隔离,可以让代码更加稳定,减少代码的修改量,从而降低维护成本。从几个层面逐渐入手:
  1. 系统分层:J2EE系统一般都划分成页面展现层,业务逻辑层和持久层。业务逻辑层容易变,而持久层变化小。对外提供服务系统分层是服务层,实现层和持久层,一般也是实现层不稳定需要经常修改,但是修改不会波及到持久层和服务层。将系统分层后,底层要更加稳定,可以新增接口或代码,但是尽量减少修改代码,因为底层一旦出错,影响面会非常广。系统间的分层也同样是需要底层系统更稳定。
  2. 代码分隔:代码上分为接口,抽象类和实现类。抽象类和接口要做到充分的抽象,从而减少修改。比如接口要符合单一原则,避免接口修改。比如Java的Closeable接口里只有一个close方法,指责非常单一,所以无论未来有什么场景,基本不会修改这个接口。如果你的接口里有很多其他职责的方法,一旦一个方法修改,很多实现类就必须跟着修改。
http://ifeve.com/talk-architecture/
http://mp.weixin.qq.com/s?__biz=MzI4MjA4ODU0Ng%3D%3D&idx=1&mid=401373742&sn=e27102eda726a2a56ee097013c2754ac

论架构师的自我修养
中小型网站架构分析及优化
第二层:反向代理(网页缓存)
  如果CDN没有缓存要请求的数据则向这层发起请求,在代理服务器配置缓存功能(本地),代理服务器就查找本地缓存是否有CDN请求的数据,如果有就直接返回给CDN,如果没有则请求后端负载均衡器然后转发给WEB服务器返回数据给代理服务器,代理服务器再将结果给CDN。代理服务器一般缓存不经常变动的静态页面,如image、js、css、html等,主流的缓存软件有Squid、Varnish、Nginx。
第三层:负载均衡
  访问量较大的网站都会用到负载均衡,因为这是解决单台服务器性能瓶颈的最好办法。反向代理将请求转发给负载均衡器,负载均衡器根据算法(轮训、负载情况选择后端等)交给后端WEB服务处理,WEB服务处理完成后直接返回数据给反向代理服务器。负载均衡合理分配请求给后端多台WEB服务器,减轻单台服务器并发负载,并保证服务可用性。主流的负载均衡软件有LVS、HAProxy、Nginx。


第五层:动静分离
  动静分离,顾名思义,是将动态页面和静态页面分离到不同服务器上处理,比如使用web是nginx,可以让fastcgi部署到单独一台服务器,专门解析php动态页面,静态页面默认由nginx处理,并做好缓存策略。再比如一个商城网站,会有大量的图片,可以考虑增加文件服务器组,将请求图片和上传图片的都交给文件服务器处理。文件服务器主流使用NFS,存在单点故障,可以DRBD+HeartBeat+NFS部署高可用,如果单台压力过大,考虑使用分布式文件系统,如GlusterFS、MooseFS等。
DRBD+HeartBeat+NFS博文:http://lizhenliang.blog.51cto.com/7876557/1362539

核心思路:减少请求层,尽可能让前端层返回用户请求的数据,减少后端服务器访问频率,最重要是数据库层。

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts