跟随,学习,进步

黄药师

Joey's Notes | 黄药师的笔记本

https://notes.miaowu.org/

积累一些知识和笔记在这里,以供自己和他人参考。摄影和爱猫一样重要,代码的灵性在于生活的感悟。

转到作者网站

为什么我们需要use_cases

我一直以为,在写rails的时候使用use_case是一种很常见的意识。但是我发现还是有一部分人从来没用过或者没听说过use_case,出于让自己也更仔细的思考这种用法的目的,记录一下。 事情的起因是因为一次code review, 我很庆幸我们团队内部的code review做的一直都不错,大家都很认真的给彼此的代码做认真的检查,并且都能从中学到很多东西。 我封装了一个use_case,并且在model的callback里面去调用了这个use_case。这个做法遭到了给我做code review同事的质疑,然后我才知道原来还有部分道友还不知道use_case的用法。 当然我也并不是说我这样的做法就是最好的,但是这种既不属于model,也很难成为一个公用lib class的,并且单一职责,逻辑简单的玩意儿,随着项目的成长随时可能改变的东西,封装为一个use_case绝对是一个不错的选择。 试想我们有一个表单,需要给用户发验证码,并且在用户输入验证码以后比对验证码,才能允许用户正常提交。假设这个方法叫做send_code,我们创建一个发验证码的module叫做Postman。 我们的发验证码的controller长这样: class AuthController < ApplicationController def create auth_code = AuthCode.create(sms_params) if svc.success? render json: { sid: auth_code.sid } else render json: { status: 500 }, status: 500 end end private def sms_params params.require(:verification).permit(:phone_number, :code) end end model长这样: class AuthCode < ActiveRecord::Base before_create :generate_code after_create :send_code def send_code Postman.new(phone_number, verify_code).perform end private def generate_code self.verify_code = rand.to_s[2..5].to_s end end 这样我的controller只用关心验证码的创建就好,发不发/怎么发都是model的事儿,AuthCode记录创建好以后会通过callback去发送,这里的Postman就是我们前面提到的一个use_case: class Postman include UseCase def initialize(phone_number, message) @phone_number = phone_number @message = message end def perform SMS::Client.new.messages.create( to: @phone_number, body: @message ) end end 而UseCase可以理解为一个接口定义,描述了所有use_case都需要遵循的规则,便于维护和自描述: module UseCase extend ActiveSupport::Concern include ActiveModel::Validations # extented class should contains these methods module ClassMethods # The perform method of a UseCase should always return itself def perform(*args) new(*args).tap(&:perform) end end # implement all the steps required to complete this use case def perform raise NotImplementedError end # inside of perform, add errors if the use case did not succeed def success? errors.none? end end 这里有几点需要注意的: 每个use_case只有一个public的实例方法 (perform) 每个use_case只有一个职责,也就是只做一件事(发短信) 因为上一条,所以测试也很容易写 有一个Gem叫做caze可以让use_case的调用更优雅一些,不必像我这样显式的调用: Postman.new(phone_number, verify_code).perform 具体可以看看caze的文档。 顺便发一下代码的结构: ├── app │   ├── controllers │   │   ├── application_controller.rb │   │   ├── auth_controller.rb │   │   └── users │   ├── models │   │   ├── user.rb │   │   └── auth_code.rb │   ├── use_cases │   │   ├── postman.rb │   │   └── use_case.rb 这样一来,我们就: 把程序有什么 models 比如user, auth_code 等等不怎么变化很稳定的东西。 和程序做什么 业务逻辑 和 use cases 会随着项目的成长不停改变。 分开了。 那问题来了, 我们什么时候需要 use_case 呢? 当你需要管理resources,你就必须用rails的方式,也就是面向resource的方式去做,model啦,presenter啦,抽象类啦,都是很方便且有道理的。 但是,当你的业务里面有一个很特殊的功能,它不属于你的主营业务逻辑,且职责单一,随时可以变化甚至移除,那么你就可以考虑使用use_case,就像上面的代码那样。 总结 一万个程序员眼里有一万种最佳实践,use_case不是所有的场景都适用。但是当你有这样的思维以后,对于如何组织你的use_case,如何保持代码结构整洁肯定是有一定帮助的。 Referreces Architecture the Lost Years by Robert Martin Clean architecture on rails by Fabiano Beselga caze gem use case examples


一些实用的 Docker 清理命令

工欲善其事必先利其器,docker 镜像太多会占用很多磁盘空间,垃圾回收一下是必须的工作。 杀死所有正在运行的容器 $ docker kill $(docker ps -a -q) 删除所有已经停止的容器 $ docker rm $(docker ps -a -q) 删除所有未打 dangling1 标签的镜像 $ docker rmi $(docker images -q -f dangling=true) 删除所有镜像 $ docker rmi $(docker images -q) 删除所有未运行 Docker 容器 $ docker rm $(docker ps -a -q) 删除所有未打 tag 的镜像 $ docker rmi $(docker images -q | awk '/^/ { print $3 }') 根据格式删除所有镜像 $ docker rm $(docker ps -qf status=exited) 为这些命令创建别名 # ~/.bash_aliases # 杀死所有正在运行的容器. alias dockerkill='docker kill $(docker ps -a -q)' # 删除所有已经停止的容器. alias dockercleanc='docker rm $(docker ps -a -q)' # 删除所有未打标签的镜像. alias dockercleani='docker rmi $(docker images -q -f dangling=true)' # 删除所有已经停止的容器和未打标签的镜像. alias dockerclean='dockercleanc || true && dockercleani' Dangling Images: Docker images consist of multiple layers. Dangling images, are layers that have no relationship to any tagged images. They no longer serve a purpose and consume disk space. ↩


Mac下安装rmagick遇到的问题

在 High Sierra macOS 上安装 rmagick 然后用来合成图片的时候遇到的一些问题和解决方案。 花了大半天把问题解决了,必须把遇到的问题和解决方案记录下来,还剩下X11 的问题么有解决,估计只能等rmagick更新才能得到解决了, anyway, 不影响功能,who care. demo code Environment macOS: High Sierra 10.13.4 ruby version: 2.4.2 $ gem install rmagick No package ‘MagickCore’ found ... ackage MagickCore was not found in the pkg-config search path. Perhaps you should add the directory containing `MagickCore.pc' to the PKG_CONFIG_PATH environment variable No package 'MagickCore' found checking for outdated ImageMagick version ( ~/.zshrc 仍然出现 Can’t install RMagick 2.16.0. Can’t find MagickWand.h. 思考了一下可能是PATH没换过来,回到第二个问题开始的地方 $ mdfind MagickWand.h /usr/local/Cellar/imagemagick@6/6.9.9-40/share/doc/ImageMagick-6/www/api/MagickWand/struct__MagickWand.html /usr/local/Cellar/imagemagick@6/6.9.9-40/include/ImageMagick-6/wand/magick-wand.h # ' 网搜一堆回答,看来是macOS的问题,卸载原来的 imagemagick,用x11的方式再来一次 $ brew uninstall imagemagick $ brew install imagemagick@6 --with-x11 Warning: imagemagick@6: this formula has no --with-x11 option so it will be ignored! 看来带版本的 不能这样玩儿啊。官网论坛看一下: Mac OS X binary is not X11 enabled If your issue is that you cannot display images without X11, then you need to download and install XQuartz. Apple does not provide X11 any more. See https://www.xquartz.org and https://support.apple.com/en-us/HT201341 好的看来装一下 xquartz就行 $ brew cask install xquartz == Satisfying dependencies == Downloading https://dl.bintray.com/xquartz/downloads/XQuartz-2.7.11.dmg ######################################## 62.1% 装完以后还是不行。 查了半小时Google,发现这个X11的问题只是影响 display 这个命令,这个本质上和 open 是一样一样的。囧!放弃,只要能合成图片就行了,还要什么自行车。 RMagick: unable to read font `Helvetica’ 为了能读到系统字体也是麻烦的不行,还需要安装一个不知道用来干嘛的东西。 $ brew install gs 尝试往图片上写中文乱码 字体的原因,除了需要安装 上一步 里面那个扩展,还需要下载中文字体,放在可以访问的路径,最终代码差不多这样,给背景图上加上了图片和文字:


自行搭建ELK相关事宜

本文主要介绍自己搭建一套ELK的大概流程,和遇到的一些问题。 INSTALLATION 1. 安装 Downloads,Documents 注意 logstash需要 Java8 。并且不支持Java 9. java -version 2. 拆分config文件 $ mkdir profiles $ touch profiles/request.config profiles/db.log.config $ # test configs $ bin/logstash --config.test_and_exit -f profiles/ $ # start logstash $ bin/logstash -f profiles/ 讲不同的日志过滤器拆分到各自的文件去,方便维护。注意通过type或者字段区分grok的条件。 3. Visualize 数据可视化 待添加 4. Metricbeat 待添加 5. Packetbeat 待添加 6. Heartbeat 待添加 ISSUES: 1. mongodb sytem.profile 读取方式取舍 一开始考虑用 logstash-input-mongo 的方式来读取 system.profile # /etc/logstash/conf.d/00-mongodbinput.conf input { mongodb { uri = 'mongodb://dds-xxxx.mongodb.rds.aliyuncs.com:3007/POCDB' placeholder_db_dir = '/var/local/logstash-mongodb/' collection = 'system.profile' batch_size = 500 generateId = true } } 结果发现这个插件有个过滤条件会把包含system的结果过滤掉,囧。via. logstash-input-mongodb/issues/8 然后考虑通过 plugin-inputs-file 读取日志文件的方式,结果发现阿里云不给直接读取文件。 最后选择了用 logstash-input-exec,通过命令行去获得slow query 的记录。 input { exec { command = "mongo -u readonly -p '5437a&b$2UmO' dds-xxxx.mongodb.rds.aliyuncs.com:3007/database_production --eval 'db.system.profile.find({ts : {$gt: new Date(ISODate().getTime() - 1000*60), $lt: new Date()}})' | tail -n +3" interval = 60 type = "db.serverStatus" add_field = { "dbserver" = "mongodb_log" } } } 解释一下,每60秒 (interval) 执行一次,获取60秒之前 (new Date(ISODate().getTime() - 1000*60) 到现在的慢查询日志,添加一个字段dbserver值为mongodb_log,方便在 elacticsearch 那边做数据聚合。 2. prok、filter 问题 filter { # 通过字段来选择filter if [dbserver] == "mongodb_log" { # 按行拆分为一条一条的 split { field = "message" } grok { # 不含关键词的日志都丢弃 match = ["message", "database_production"] tag_on_failure = ["drop_lines"] add_tag = ["db.log"] } grok { # logstash 本身用来做 input 的查询丢弃 match = ["message", "\.system\.profile"] add_tag = ["drop_lines"] } grok { match = ["message", "%{MONGO_QUERY:mongo_query}"] add_tag = ["mongo_query"] } grok { match = ["message", "\"ts\"%{SPACE}\:%{SPACE}ISODate\(\"%{DATA:happened_at}\"\),"] add_tag = ["mongo_query"] } grok { match = ["message", "\"millis\"%{SPACE}\:%{SPACE}%{NUMBER:spendtime:int},"] add_tag = ["mongo_query"] } grok { match = ["message", "\"client\"%{SPACE}\:%{SPACE}\"%{DATA:client_ip}\""] add_tag = ["mongo_query"] } if "mongo_query" in [tags] { mutate { remove_tag = ["_grokparsefailure"] } } # 丢掉 grok 失败的结果 if "_grokparsefailure" in [tags] { drop { } } # 丢弃选择丢弃的内容 if "drop_lines" in [tags] { drop { } } # 把查询语句丢掉,因为里面有敏感信息 mutate { remove_field = ["command"] } } } 3. logstash server cannot connect to mongo $ mongo dds-xxxx.mongodb.rds.aliyuncs.com:3007 --authenticationDatabase admin -u root -p MongoDB shell version: 2.6.10 Enter password: connecting to: dds-xxxx.mongodb.rds.aliyuncs.com:3007/test 2018-04-17T11:39:48.902+0800 DBClientCursor::init call() failed 2018-04-17T11:39:48.903+0800 Error: DBClientBase::findN: transport error: dds-xxxx.mongodb.rds.aliyuncs.com:3007 ns: admin.$cmd query: { whatsmyuri: 1 } at src/mongo/shell/mongo.js:148 exception: connect failed 以为是vpc 到ecs的 classicLink 没有配置的问题,后来老大说是mongodb的白名单。加了白名单以后,又出现了认证失败的问题: $ mongo --host dds-xxxx.mongodb.rds.aliyuncs.com:3007 --authenticationDatabase admin -u readonly -p MongoDB shell version: 2.6.10 Enter password: connecting to: dds-xxxx.mongodb.rds.aliyuncs.com:3007/test 2018-04-17T13:23:52.299+0800 Error: 18 { ok: 0.0, errmsg: "auth failed", code: 18, codeName: "AuthenticationFailed" } at src/mongo/shell/db.js:1287 exception: login failed 排除密码错误以后,推测是 mongo shell 的版本太低,阿里云的mongodb是3.+的 $ mongo --version MongoDB shell version: 2.6.10 我们是 ubuntu 16 所以卸载以后重新安装最新版, The important thing is: use mongodb-org-tools instead of mongodb-clients $ sudo apt-get remove mongodb-clients $ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 $ echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list $ sudo apt-get update $ sudo apt-get install mongodb-org-tools $ sudo apt-get install mongodb-org-shell=3.2.19 依然认证失败 $ mongo --host dds-xxxx.mongodb.rds.aliyuncs.com:3007 --authenticationDatabase admin -u readonly -p MongoDB shell version: 3.2.19 Enter password: connecting to: dds-xxxx.mongodb.rds.aliyuncs.com:3007/test 2018-04-17T13:47:26.365+0800 E QUERY [thread1] Error: Authentication failed. : DB.prototype._authOrThrow@src/mongo/shell/db.js:1441:20 @(auth):6:1 @(auth):1:2 exception: login failed 用 root 用户登录没问题 readonly账号还是认证失败,考虑是不是 readonly 账号没有权限,via. StackoverFlow - MongoDB 3.2 authentication failed MongoDB云数据库常见问题诊断 最后发现是数据库名字不对。o(╯□╰)o


修改SublimeText侧边栏的字体大小

使用ST3的过程中,想对ST做一些个性化调整,比如sidebar里文件列表的字体大小。 写代码的时候我可以接受字体小一点,但是sidebar涉及鼠标点击事件,字体太小容易点错。 所以尝试修改sidebar的字体,其实类推这里可以做很多个性化定制: 打开Sublime Text 的 Preferences(个人偏好) - 浏览插件(Browse Packages) 打开 User 目录 创建一个新文件 Default.sublime-theme,如果你没有使用默认主题而是自己的主题的话,比如我是 itg.flat.dark.sublime-theme 那文件名就是 itg.flat.dark.sublime-theme, 写入 [ { "class": "sidebar_label", "color": [0, 0, 0], "font.bold": false, "font.size": 12 } ] 实测你可以去掉 color 那一行,或者自己修改成自己喜欢的颜色。 保存及时生效,如果没生效肯定是文件名错了。 还有很多参数可以配置,可以参考一下:Default.sublime-theme 我只列出一部分: [ { "class": "label_control", "color": [255, 255, 255], "shadow_color": [24, 24, 24], "shadow_offset": [0, -1] }, { "class": "button_control", "content_margin": [6, 5, 6, 6], "min_size": [75, 0], "layer0.texture": "Theme - Default/full_button.png", "layer0.opacity": 1.0, "layer0.inner_margin": [6, 6], "layer1.texture": "Theme - Default/full_button_indented.png", "layer1.opacity": 0.0, "layer1.inner_margin": [6, 6], "layer2.texture": "Theme - Default/blue_highlight.png", "layer2.opacity": { "target": 0.0, "speed": 1.33, "interpolation": "smoothstep" }, "layer2.inner_margin": [6, 6] } ]


解决MacOS升级后出现xcrun: error

本文解决MacOS升级后出现xcrun: error: invalid active developer path, missing xcrun的问题。 今天升级macOS High Sierra,终端里使用git的时候,弹出一行莫名其妙的错误: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun 解决方法,重装xcode command line: $ xcode-select --install 如果没有解决问题,执行以下命令 $ sudo xcode-select -switch /


浅谈敏捷开发和Scrum

行业内有太多人吐槽敏捷开发,原因各不相同,有觉得 Agile 就是一坨翔的,有觉得 Agile 太低效的,也有觉得团队小暂时不需要敏捷的,etc。 人的本性都是敏捷的,谁都不想浪费宝贵的时间。抱怨敏捷的人,一是对敏捷理解不够深刻,生搬硬套,觉得不行,然后就一大堆抱怨;二是老板觉得敏捷不能完全的压榨劳动力,也就是行业金句——工作不饱和。 美国人埃里克·莱斯提出了《精益创业》的方法论,它强调的是在风险极高、创业资本有限的情况下,需要快速摸索出最小化可行产品(MVP)尽早进行市场验证,现在精益创业已风行创业领域,但是如何将此方法论具体应用到创业团队产品开发的实践之中?很多创业公司/团队声称自己的精益创业,然而却对团队管理漠不关心,更别说敏捷开发,开发流程乱七八糟,全是小作坊操作,美其名曰:我们要快速的迭代产品,顾不上这些。 我在敏捷的团队做过好几年,敏捷的目的并不是为了让开发事儿更少,而是让大家在有限的时间效率更高。在工作量不变的情况下,更少加班;在工作时间不变的情况下,产出更大。 在欧美软件企业中,有近半数企业已采用敏捷方法进行开发,硅谷FLAG,国内如腾讯、阿里、百度、Fackbook、Yahoo!等等一线互联网公司内部几乎所有的开发团队都在实施敏捷方法。相关统计表明,敏捷开发可以将效率提高3~10倍,项目质量也有更加可靠的保证。 什么是敏捷开发? 敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。 怎么理解呢?首先,我们要理解它不是一门技术,它是一种开发方法,也就是一种软件开发的流程,它会指导我们用规定的环节去一步一步完成项目的开发;而这种开发方式的主要驱动核心是人;它采用的是迭代式开发; 为什么说是以人为核心? 我们大部分人都学过瀑布开发模型,它是以文档为驱动的,为什么呢?因为在瀑布的整个开发过程中,要写大量的文档,把需求文档写出来后,开发人员都是根据文档进行开发的,一切以文档为依据;而敏捷开发它只写有必要的文档,或尽量少写文档,敏捷开发注重的是人与人之间,面对面的交流,所以它强调以人为核心。 什么是迭代? 迭代是指把一个复杂且开发周期很长的开发任务,分解为很多小周期可完成的任务,这样的一个周期就是一次迭代的过程;同时每一次迭代都可以生产或开发出一个可以交付的软件产品。 敏捷的套路 —— 实践框架 XP(极限编程)较早出现在中国的原因,得益于当初翻译的几本书(2001年),不过有点极端了,很多传统企业都不能适应。 Scrum 是精益创业很好的实践方法,概念清晰,可操作性强,落地快,在中国也出现了日渐普及的态势;当然骂声也不少,认为它什么都没讲,太虚了。实际上他们大多数人把自身的问题归结于 Scrum 了。 FDD(Feature Driven Development)等还有一些其他的过程,声音慢慢就越来越少了。 目前流行的敏捷套路就只有 Scrum 而已,另外一些都越来越少有被人提起了。 这里,我们主要以 Scrum 来讲解敏捷,但千万别以为 Scrum 就是敏捷。 关于Scrum和XP 前面说了敏捷它是一种指导思想或开发方式,但是它没有明确告诉我们到底采用什么样的流程进行开发,而 Scrum 和 XP 就是敏捷开发的具体方式了,你可以采用 Scrum 方式也可以采用 XP 方式;Scrum 和 XP 的区别是,Scrum 偏重于过程,XP 则偏重于实践,但是实际中,两者是结合一起应用的,这里主要讲 Scrum。 Scrum 关键词汇解释 product backlog: 可以预知的所有任务, 包括功能性的和非功能性的所有任务。 sprint: 一次跌代开发的时间周期,一般最多以30天为一个周期.在这段时间内,开发团队需要完成一个制定的backlog,并且最终成果是一个增量的,可以交付的产品。 sprint backlog: 一个 sprint 周期内所需要完成的任务。 Scrum Master: 确保团队合理的运作 Scrum,并帮助团队移除实施中的障碍。 PO (Product Owner): 即产品负责人,确定产品的方向和愿景,定义产品发布的内容、优先级及交付时间,为产品负责。 scrum team(开发团队): 一个跨职能的小团队,包括开发测试,人数5-9人为佳,团队拥有交付可用软件需要的各种技能。 time-box: 一个用于开会时间段。比如每个 daily scrum meeting(每日站立会议) 的time-box为15分钟。 sprint planning meeting: 在启动每个sprint前召开。该会议需要制定的任务是:PO 和团队成员将 backlog 分解成小的功能模块,决定在即将进行的 sprint 里需要完成多少小功能模块,确定好这个 Product Backlog 的任务优先级。另外,该会议还需详细地讨论如何能够按照需求完成这些小功能模块。制定的这些模块的工作量以小时计算。 Daily Scrum meeting:开发团队成员召开,一般为15分钟。每个开发成员需要向 team 汇报三个项目: 昨天完成了什么,完成了百分之多少,还剩百分之多少? 今天你打算做什么? 完成你的目标是否存在什么障碍? 通过该会议,团队成员可以相互了解项目进度。 Sprint review meeting:在每个 Sprint 结束后,这个Team将这个 Sprint 的工作成果演示给 Product Owner,客户,老板和其他相关的人员。 Sprint retrospective meeting:对刚结束的Sprint进行总结。会议的参与人员为团队开发的内部人员。一般该会议为1小时。 什么是scrum? Scrum的基本假设是: 开发软件就像开发新产品,无法一开始就能定义软件产品最终的规程,过程中需要研发、创意、尝试错误,所以没有一种固定的流程可以保证专案成功。Scrum 将软件开发团队比拟成橄榄球队,有明确的最高目标,熟悉开发流程中所需具备的最佳典范与技术,具有高度自主权,紧密地沟通合作,以高度弹性解决各种挑战,确保每天、每个阶段都朝向目标有明确的推进。 Scrum 开发流程通常以 30 天(或者更短的一段时间)为一个阶段,由客户提供新产品的需求规格开始,开发团队与客户于每一个阶段开始时挑选该完成的规格部分,开发团队必须尽力于 30 天后交付成果,团队每天用 15 分钟开会检查每个成员的进度与计划,了解所遭遇的困难并设法排除。 Scrum 三大角色 Scrum“角色”–无规矩不成方圆 PO 必须有一个项目持有者,制定规划并把握项目走向,一般就是产品经理。 SM 敏捷教练。一般由对技术开发以及当前项目明晰的技术经理担任。 TEAM Scrum 的流程 引用一张图,结合上面的名词解释: 我们首先需要确定一个 Product Backlog(按优先顺序排列的一个产品需求列表),这个是由 Product Owner 负责的; 正式开始一个 sprint 开始之前,产品、研发、测试需要一同开一次 sprint planning meeting,共同讨论本次 sprint 的功能点,需求讨论或技术讨论;成员预估需求所需开发时间;团队输出是否满足需求,排入 sprint backlog; planning meeting 下来之后每个团队成员对自己在这个sprint中的工作进行整理,拆分小任务,预估开发完成时间,自己排自己的优先级; 进行 Daily Scrum Meeting,这个环节在 agile 中非常关键,是 agile 的日常修炼,控制在15分钟左右,每个人都必须发言,并且要向所有成员当面汇报你昨天完成了什么,并且向所有成员承诺你今天要完成什么,同时遇到不能解决的问题也可以提出来寻求帮助。完了以后SM负责根据结果更新 burndown chart; 当一个 Sprint 结束时,我们要进行 Sprint Review Meeting,也称为评审会议,产品负责人和客户都要参加,每一个Scrum Team的成员都要向他们演示自己完成的软件产品(这个会议非常重要,一定不能取消); 最后就是 Sprint Retrospective Meeting,复盘这个 sprint,以轮流发言方式进行,每个人都要发言,总结并讨论做得好的地方、需要改进的地方;根据实际情况进行下一个 sprint 的任务安排。 这样周而复始,按照同样的步骤进行下一次Sprint. Scrum 的特性 不断交付软件以满足客户需求,每个迭代版本都是可运行的 欢迎需求的变化 及时沟通,拒绝过度设计 量化了工作项目的进度和团队的产出 流程简单,沟通顺畅 随便总结一下 敏捷是一种流程、方法、理念,甚至信仰; 敏捷不是一种工具,不是用了敏捷的软件就是敏捷了; 敏捷是为了团队成员能够更加紧密地配合完成工作; 敏捷是需要本土化的,可以根据项目团队的情况指定自己的敏捷计划。 以后也许会补充


[初闻道]在mac上安装docker,及docker-compose

现在流行用docker作容器来开发部署。 本文主要解决在mac上安装docker[-compose],以及启动一个nginx实例。 Requirement 系统要求 Docker for Mac 要求系统最低为 macOS 10.10.3 Yosemite。如果系统不满足需求,可以安装 Docker Toolbox。 提前安装好 zsh homebrew sublime text or vim 安装 使用 Homebrew 安装 macOS 我们可以使用 Homebrew 来安装 Docker: $ brew cask install docker == Creating Caskroom at /usr/local/Caskroom == We'll set permissions properly so we won't need sudo in the future Password: # 输入 macOS 密码 == Satisfying dependencies == Downloading https://download.docker.com/mac/stable/23608/Docker.dmg ######################################################################## 100.0% == Verifying checksum for Cask docker == Installing Cask docker == Moving App 'Docker.app' to '/Applications/Docker.app'. 🍺 docker was successfully installed! 在载入 Docker app 后,点击 Next,可能会询问你的 macOS 登陆密码,你输入即可。之后会弹出一个 Docker 运行的提示窗口,状态栏上也有有个小鲸鱼的图标()。 ###手动下载安装 如果需要手动下载,请点击以下链接下载 Stable 或 Edge 版本的 Docker for Mac。 双击下载的 .dmg 文件,然后将鲸鱼图标拖拽到 Application 文件夹即可。 从应用中找到 Docker 图标并点击运行, 或者呼出Alfred输入docker回车。可能会询问 macOS 的登陆密码,输入即可。 点击状态栏的图标可以得到操作菜单。 第一次点击图标,可能会看到这个安装成功的界面,点击 “Got it!” 可以关闭这个窗口。 这里有个小提示: 自己注册一个 docker 的账号,然后在小鲸鱼菜单里面登录 登录的时候用ID登录,不要用email,否则后续的命令行可能会出现 Unable to find image 'nginx:latest' locally docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/nginx/manifests/latest: unauthorized: incorrect username or password. See 'docker run --help'. 要找到自己的ID很简单,打开 docker store, 登录以后看右上角,头像旁边就是自己注册的ID 启动终端后,通过命令可以检查安装后的 Docker 版本。 $ docker --version Docker version 17.12.0-ce, build c97c6d6 $ docker-compose --version docker-compose version 1.18.0, build 8dd22a9 $ docker-machine --version docker-machine version 0.13.0, build 9ba6da9 Docker for Mac 和 Docker Toolbox 已经包含了 Compose 了, 所以 Mac 用户不用单独安装Compose了。 如果 docker version、docker info 都正常的话,可以尝试运行一个 Nginx 服务器: $ docker run -d -p 80:80 --name webserver nginx 参数的含义和用法参考网上的文档 服务运行后,可以访问 http://localhost,如果看到了 “Welcome to nginx!”,就说明 Docker for Mac 安装成功了。 要停止 Nginx 服务器并删除执行下面的命令: $ docker stop webserver $ docker rm webserver 有些用户会觉得国内网络拉取docker镜像速度很慢,可能需要配置加速服务器。网上有人分享自己的加速地址,可以参考配置一下。


[初闻道]搭建mac开发环境

拿到一台mac以后怎么初始化开发环境. 本文主要以rails为例子,介绍拿到新的rmbp以后如何迅速搭建开发环境,并推荐一些基础软件。 确定安装了xcode开发工具 一般来讲默认都是安装好的 $ xcode-select --version xcode-select version 2349. 安装iterm2 http://iterm2.com 下载安装就行,打开以后保留在dock里面,方便以后快速打开. 这是主力开发工具之一 安装homebrew https://brew.sh 打开iterm2, 粘贴以下命令回车,根据提示继续操作就行 $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 中间可能会需要授权,输入mac的登录密码就可以了。 安装时间根据网络情况可能会比较长,半个小时左右吧,慢慢等。 等homebrew装完以后就方便多了,很多软件都可以用brew来安装. 相关命令可以查阅网站文档 安装zsh,oh-my-zsh 用brew安装文档是很方便的 install ZSH via wiki http://github.com/robbyrussell/oh-my-zsh $ brew install zsh zsh-completions $ zsh --version zsh 5.4.2 (x86_64-apple-darwin17.3.0) 安装oh-my-zsh的话可能需要先安装wget 或者 curl $ brew install wget $ sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)" 安装完 oh-my-zsh 以后,拷贝一个 zsh的配置过来 $ cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc 配置zshrc,oh-my-zsh 第一个就是换成自己喜欢的theme,用起来顺手顺眼. Themes 我喜欢的是 agnoster 这个theme,所以先修改配置 然后根据提示去安装字体,via fonts-powerline git clone https://github.com/powerline/fonts.git --depth=1 cd fonts ./install.sh cd .. rm -rf fonts 然后打开iterm的偏好设置,修改默认字体 不喜欢iterm配色还可以去下载一堆回来慢慢试. iTerm Themes 安装sublime text 或者 vim http://www.sublimetext.com/3 我个人的习惯是给sublime text设置一个命令行启动 $ ln -f -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl 记得在~/.zshrc 里面加上PATH 或者去掉该行注释 这样的好处是可以从命令行快速的用sublime打开文件 $ subl ~/.zshrc sublime text 有一堆的插件,这个在另外的笔记里面去介绍。 安装 rbenv 开发rails的话目前推荐用 rbenv管理本地的ruby版本, via . rbenv $ brew install rbenv $ brew install ruby-build 配置github的ssh key 目的是为了本地命令行不用每次都输入GitHub的账号密码 https://github.com/settings/keys https://help.github.com/articles/connecting-to-github-with-ssh/ # 生成 ssh key # 一路回车,除非有特别需求,可以看看上面的链接文档 $ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # 拷贝 ssh keys $ pbcopy