微服务之道
道
"道"原本是起源于中国, 道教也是土生土长于中国的宗教, 所谓墙里开花墙外香, 道和道教在中国并未大行其道.
程序员的世界中, 记得的一本坐而论道的书也是老外写的"The Tao Of Programming".
其实,道已经扎根于每个中国人的内心世界,道是真理,是过程,是事物的本质, 是自然的规律.
道可道,非常道. 真正的大道, 不是几句话可以说明白的,也不是仅用言语可以说得清楚透彻的.
然而道也是可以道的, 道需领悟, 先要知道.
软件之道
最早大家提到软件, 就是相对于硬件设备来说的, 一般分为系统软件和应用软件.
软件一般是装在磁盘和光盘里的, 一个漂亮的包装盒子, 买回家在电脑上安装好后就可以用了
SaaS 即Software as a service, 软件即服务是互联网发展的产物, 它是对传统软件的一场革命.
从此,软件开发将不再是第二产业,而是第三产业了. 软件可以不再是卖的的, 而是租的,或者是免费使用的(条件是用户对广告的容忍)
套用老板常说的一句话,"不要问公司可以给你什么,先要问你可以为公司做什么", 用户所关心的也是"不要问我可以付给你多少钱,先要问你可以为我做什么"
传统的软件软件巨头日子都不太好过,Sun被Oracle收购了, 微软面临艰难转型, 而SaaS的代表Salsforce, WebEx都活得有滋有味.
究其原因, SaaS凭借易用性和经济性, 在互联网的任一端点,牢牢地占据了用户, "你能为我做多少,我就付给你多少"的商业模式颇受欢迎.
SaaS也给程序员带来了机会, 中国的程序员创业不再遥不可及,没有关系,没有背景,只要提供的服务好用,需要花费的成本够低 ,一定会有用户愿意为你提供的优良服务掏腰包的
Saas生存之道的关键也就是服务质量和成本控制
服务质量简单说起来就是满足用户的需求, 具体有七大要点
- 功能性
- 稳定性
- 可靠性
- 性能
- 可维护性
- 可移植性
- 灵活性
成本控制的关键因素在人, 由于软件本身的硬件成本所占比重越来越低, 运行软件的服务器,处理器,存储器价格越来越低, 最重要的软件开发的人力成本, 时间成本多取决于软件开发人员.
所以软件开发一定要以人为本
敏捷之道
速度和质量是软件项目成功的两大关键因素, 不是我不明白, 这世界变化快. 面对纷繁复杂的用户需求和产品特性 唯一不变的是变化, 如何优雅地应对变化, 让工作和生活变得更简单,更从容呢
首先, 如老子所说, "图难于其易,为大于其细", 软件如同建筑, 万丈高楼平地起, 从小到大, 从易变难, 逐渐演化成用户真正需要和满意的产品
首先我们先谈谈几个软件开发的普适原则
KISS
- KISS: Keep It Simple and Straight 保持简单和直接, 适当隐藏复杂性
或者
- KISS: Keep It Simple and Stupid 保持简单, 象傻瓜一样, 不要让别人多加思考
软件接口或 API 的设计要让人一看就明白, 一看就知道作者的意图和想法, 如何使用它, 有什么结果和可能的异常及副作用
DOTADIW
Do One Thing and Do It Well 就做一件事并做好它
我非常欣赏 Unix 和 Python 的设计哲学
The UNIX 的哲学
Mike Gancarz (X window的设计者之一)总结了关于 Unix 的九大格言
英文 | 中文 |
---|---|
Small is beautiful. | 小就美 |
Make each program do one thing well. | 让一个程序就做一件事 |
Build a prototype as soon as possible. | 尽可能快的做个原型 |
Choose portability over efficiency. | 选择可移植性胜过效率 |
Store data in flat text files. | 保存数据在纯文本文件中 |
Use software leverage to your advantage. | 使用软件来增加你的优势 |
Use shell scripts to increase leverage and portability. | 用shell脚本来增进 |
Avoid captive user interfaces. | 避免交互式的用户界面 |
Make every program a filter. | 使每个程序成为过滤器 |
还有就是 Python 所倡导的 Python 之禅
Python 之禅
虽然说的是Python, 其实适用于多数编程语言
英文 | 中文 |
---|---|
Beautiful is better than ugly. | 美比丑好 |
Explicit is better than implicit. | 明显比隐晦好 |
Simple is better than complex. | 简单比复杂好 |
Complex is better than complicated. | 复杂比难懂好 |
Flat is better than nested. | 扁平比嵌套好 |
Sparse is better than dense. | 稀疏比稠密好 |
Readability counts. | 可读性很重要 |
Special cases aren't special enough to break the rules. | 特例也不要打破这个原则 |
Although practicality beats purity. | 尽管实践会破坏纯洁性 |
Errors should never pass silently. | 错误还是不能让其悄然滑过 |
Unless explicitly silenced. | 除非你明确声明不用理会它 |
In the face of ambiguity, refuse the temptation to guess. | 别让人来猜测不确定的可能性 |
There should be one-- and preferably only one --obvious way to do it. | 应该有一个且只有一个比较好的明显的方法来做事 |
Although that way may not be obvious at first unless you're Dutch. | 尽管那个方法可能并非一开始就显而易见 |
Now is better than never. | 现在就做比永远不做好 |
Although never is often better than right now. | 尽管永远不做经常比马上就动手做好 |
If the implementation is hard to explain, it's a bad idea. | 如果实现很难解释清楚, 那它不是一个好主意 |
If the implementation is easy to explain, it may be a good idea. | 如果实现很容易说清楚, 那它是个好主意 |
Namespaces are one honking great idea – let's do more of those! | 命名空间是个绝妙点子, 让我们那样做得更多 |
微服务之道
从上面诸多软件开发的原则和哲学思想来看, 庞大而复杂的系统是使众多开发人员陷入软件泥潭不能自拔的主要原因.
老子云:
图难于其易,为大于其细。天下难事必作于易,天下大事必作于细。是以圣人终不为大,故能成其大。夫轻诺必寡信,多易 必多难。是以圣人犹难之,故终无难矣。
所以我们所做的软件系统应该使用微服务
- 不要大, 要小
- 不要复杂, 要简单
- 不要松散, 要紧凑
- 不要过于依赖别人, 要独立自主
- 不要只为自己着想, 要为他人服务
这就是微服务之道, 例如豆瓣所提供的书籍信息和评分服务,
可以通过如下HTTP API 来获取图书的基本信息和评分
只要我们知道书的 ISBN 号, 我们就可在调用豆瓣的 API 的获取它的评分和基本信息
curl https://api.douban.com/v2/book/isbn/9787115376756
{
"rating": {
"max": 10,
"numRaters": 23,
"average": "8.2",
"min": 0
},
"subtitle": "软件核心复杂性应对之道",
"author": [
"[美] Eric Evans"
],
"pubdate": "2016-6-1",
"tags": [
{
"count": 19,
"name": "领域模型",
"title": "领域模型"
},
{
"count": 18,
"name": "软件工程",
"title": "软件工程"
},
{
"count": 12,
"name": "软件架构",
"title": "软件架构"
},
{
"count": 12,
"name": "设计模式",
"title": "设计模式"
},
{
"count": 8,
"name": "计算机",
"title": "计算机"
},
{
"count": 7,
"name": "程序设计",
"title": "程序设计"
},
{
"count": 5,
"name": "软件开发",
"title": "软件开发"
},
{
"count": 5,
"name": "经典",
"title": "经典"
}
],
"origin_title": "Domain-Driven Design: Tackling Complexity in the Heart of Software",
"image": "https://img3.doubanio.com/mpic/s28820730.jpg",
"binding": "平装",
"translator": [
"赵俐",
"盛海艳",
"刘霞"
],
"catalog": "...",
"pages": "370",
"images": {
"small": "https://img3.doubanio.com/spic/s28820730.jpg",
"large": "https://img3.doubanio.com/lpic/s28820730.jpg",
"medium": "https://img3.doubanio.com/mpic/s28820730.jpg"
},
"alt": "https://book.douban.com/subject/26819666/",
"id": "26819666",
"publisher": "人民邮电出版社",
"isbn10": "7115376751",
"isbn13": "9787115376756",
"title": "领域驱动设计",
"url": "https://api.douban.com/v2/book/26819666",
"alt_title": "Domain-Driven Design: Tackling Complexity in the Heart of Software",
"author_intro": "Eric Evans “领域驱动设计之父”,世界杰出软件建模专家。他创建了Domain Language公司,致力于帮助公司机构创建与业务紧密相关的软件。他在世界各地宣讲领域驱动设计(Domain-Driven Design,DDD)的思想,开设课程,参加会议,接受专访,拥有大批的追随者。从20世纪80年代开始,他就以设计师和程序员的双重身份参与过许多大型面向对象系统的设计和开发,涉及各种复杂的业务和技术领域。同时,他还培训和指导过许多开发团队开展极限编程实践。",
"summary": "本书是领域驱动设计方面的经典之作,修订版更是对之前出版的中文版进行了全面的修订和完善。\n全书围绕着设计和开发实践,结合若干真实的项目案例,向读者阐述如何在真实的软件开发中应用领域驱动设计。书中给出了领域驱动设计的系统化方法,并将人们普遍接受的一些实践综合到一起,融入了作者的见解和经验,展现了一些可扩展的设计新实践、已验证过的技术以及便于应对复杂领域的软件项目开发的基本原则。",
"price": "69"
}
让我们再花五分钟写50行代码做一个时间服务器来获取时间
- 在当下或指定的时间
- 在指定的时区
- 按指定的格式显示
使用 python 的微框架 Flask 40行代码搞定
#! /usr/bin/env python
from datetime import datetime
from dateutil import tz
from flask import make_response
from flask import Flask
from flask import request
import json
app = Flask(__name__)
def generate_response(arg, response_code=200):
response = make_response(json.dumps(arg, sort_keys = True, indent=4))
response.headers['Content-type'] = "application/json"
response.status_code = response_code
return response
@app.route("/datetime")
def get_data_time():
zone = request.args.get('timezone', 'CST' )
fmt = request.args.get('format', '%Y-%m-%d %H:%M:%S')
input_time_str = request.args.get('time', '')
from_zone = tz.tzutc()
to_zone = tz.gettz(zone)
output_time = datetime.utcnow().replace(tzinfo=from_zone)
if input_time_str and fmt:
output_time = datetime.strptime(input_time_str,fmt)
str = output_time.astimezone(to_zone).strftime(fmt)
return generate_response({"datetime": str, "timezone": zone, "format": fmt})
if __name__ == '__main__':
app.run(debug=True)
测试一下想要看的时区以及格式, 即可看到在不同时区的时间
-
执行
python datatime.py
-
输入
http://localhost:5000/datetime?timezone=America/Los_Angeles&format=%m/%d/%Y%20%H:%M:%S
- 输出:
{
datetime: "02/26/2017 07:34:04",
format: "%m/%d/%Y %H:%M:%S",
timezone: "America/Los_Angeles"
}
是不是很简单, 用起来也很方便?