thinkwei

thinkwei 查看完整档案

郑州编辑商丘师范学院  |  计算机科学与技术 编辑河南宇通信息技术有限公司  |  PHP开发工程师 编辑 thinkwei.cn 编辑
编辑

自强不息,厚德载物!

个人动态

thinkwei 关注了用户 · 3月2日

Bohr @coding101

不学习,如何肩负全面建设社会主义现代化任务。

关注 2942

thinkwei 收藏了文章 · 3月1日

PHP实现网页截图?

如何使用PHP实现网页截图

PHP实现网页截图是一个在日常开发中不常见的需求,但是如果实现还是非常有意思的。目前业界有很多成熟的方案,下面我推荐使用一个很稳定的第三方服务来直接实现,该服务有如下特点:

  • 支持多线路
  • 支持登录截图
  • 支持UA变换
  • 支持Cookie注入 实现登录截图
  • 支持自定义宽高
  • 支持网页滚动截图
  • 支持设定截图前的延迟时间

首先我们打开 它的首页 https://www.screenshotmaster.com/ 注册一个账号,然后你会在用户中心获取到一个唯一的Token,保存好这个Token 不要泄漏!

下面来看看它支持的参数:

网页截图API参数

您可以前往API文档页面查看更多的参数。

使用PHP调用截屏大师的接口获取截图:

//参数
$token = 'YOUR_API_TOKEN';
$url = urlencode('https://www.baidu.com');
$width = 1200;
$height = 800;
$full_page = 1;

// 构造URL
$query = "https://www.screenshotmaster.com/api/v1/screenshot";
$query .= "?token=$token&url=$url&width=$width&height=$height&full_page=$full_page";

// 调用API
$image = file_get_contents($query);

// 保存截图
file_put_contents('./screenshot.png', $image);

然后?没有然后了,就这么简单!
Enjoy Yourself!

查看原文

thinkwei 赞了文章 · 3月1日

PHP实现网页截图?

如何使用PHP实现网页截图

PHP实现网页截图是一个在日常开发中不常见的需求,但是如果实现还是非常有意思的。目前业界有很多成熟的方案,下面我推荐使用一个很稳定的第三方服务来直接实现,该服务有如下特点:

  • 支持多线路
  • 支持登录截图
  • 支持UA变换
  • 支持Cookie注入 实现登录截图
  • 支持自定义宽高
  • 支持网页滚动截图
  • 支持设定截图前的延迟时间

首先我们打开 它的首页 https://www.screenshotmaster.com/ 注册一个账号,然后你会在用户中心获取到一个唯一的Token,保存好这个Token 不要泄漏!

下面来看看它支持的参数:

网页截图API参数

您可以前往API文档页面查看更多的参数。

使用PHP调用截屏大师的接口获取截图:

//参数
$token = 'YOUR_API_TOKEN';
$url = urlencode('https://www.baidu.com');
$width = 1200;
$height = 800;
$full_page = 1;

// 构造URL
$query = "https://www.screenshotmaster.com/api/v1/screenshot";
$query .= "?token=$token&url=$url&width=$width&height=$height&full_page=$full_page";

// 调用API
$image = file_get_contents($query);

// 保存截图
file_put_contents('./screenshot.png', $image);

然后?没有然后了,就这么简单!
Enjoy Yourself!

查看原文

赞 6 收藏 3 评论 2

thinkwei 回答了问题 · 2月24日

解决该怎么跟后端沟通

如果返回的数据过多造成接口速度慢,可以让他去优化。

关注 17 回答 14

thinkwei 赞了文章 · 2月3日

2020年思否有奖征文获奖名单公布,快来领奖!

小伙伴们,思否年度有奖征文活动,开奖咯~
活动截止1月31日晚上12点,下面就让我们正式公布一下此次年度总结活动的获奖名单~


2020 人气顶流奖

  1. 夜尽天明前端工程师的 2020 年终总结 - 成长不及预期的 3 年之痒
  2. 蒋鹏飞工作都是公司的,技术才是自己的!| 底层技术人的2020年度总结
  3. axuebin:一个小小前端的 2020 年流水账
社区文章互动数多的(基于点赞、评论等)的3人
融云鼠标垫 + ARM 蓝牙音箱 + 京东玩偶 + 编程课程 8 折劵 各一份(文中列出的课程)

2020 凡尔赛文学奖

  1. 死月死月的二零二零总结
  2. CrazyCodes2021 PHP程序员修炼秘籍
  3. 张晋涛2020 小回顾 | 新晋程序员奶爸的云原生之路
文笔超赞/分享硬核干货内容的 3 人
青云定制包 + AWS 玩偶 + 技术书籍 + 编程课程 8 折劵 各一份(文中列出的课程)

2020 搞笑担当奖

  1. 卡颂:大佬那么多,为什么不能是我 | 卡颂2020年终总结
  2. pingan87872020 总结 | 21 张图总结我的 2020 年
  3. 沉默王二2020总结文章|乘风破浪的一年
内容超有趣的 3 人
京东鼠标垫 + AWS 玩偶 + ARM 蓝牙音箱 + 编程课程 8 折劵 各一份(文中列出的课程)

2020 人间真爱奖

  1. 欧雷属于我的三年·第一年
  2. Kevinwan一个20年技术老兵的 2020 年度技术总结
  3. 小傅哥2020总结 | 作为技术号主的一年!
  4. 民工哥我的 2020 年是这样的。。你的呢?
  5. 沈唁今天,告别 2020 年。
  6. masonli“措手不及”的2020 | 2020总结
  7. 敲键盘的猫我的2020,在非常时期的非常努力
  8. 皮小蛋2020 年终总结
  9. Why技术2020,我这一年。
  10. xuexiangjys年终总结 | 在开源、博客和搬砖的路上砥砺前行「2020」
  11. codecraft2020年终总结
  12. 公丕昊再见,2020
  13. robin2020,再见
  14. linong2020总结😊我想混个奖品
  15. YourbatmanYourBatman 2020年感悟关键词:科比、裁员、管理层、活着
  16. 边城边城客栈的 2020
  17. Fw恶龙2020 年终盘点
  18. 波波Nadia我的 2020 个人成长回顾:花足够长的时间,有智慧地做“无用功”
  19. 折腾不止的追梦人我的2020,啪啪打脸
  20. Kense2020 年终总结
  21. 一个优秀的废人来年,做个俗人!
  22. formulahendry我的 2020:出书、办签售会、发展 VS Code 中文社区、成为开源先锋、全网 10 万粉丝、10 场演讲、内推 21 人
  23. 程序员哆啦A梦2020回顾-个人web分享JavaScript面试题附加回答
  24. Shenfq:普普通通打工人的2020
  25. HLQ\_Struggle静心,未来可期 | 告别 2020
  26. Raymond懒人的2020
  27. xindooXINDOO的2020总结
  28. tina6662020 疫情下湖北人的生活(只谈生活)
  29. 张喜硕度光阴的人
  30. JerryWang\_汪子熙一个SAP成都研究院开发工程师的2020年度总结:未知生,焉知死
  31. JamesGoodbye 2020 wassup 2021 | 2020 总结
  32. howie梦想开始的地方
  33. 运维汪回顾2020,展望202,确定三个关键字:自我成长、打地基、过男人关
  34. zangecizangeci的2020年度报告
  35. Meathill2020 年知识分享与学习总结
  36. 寒雁2021,一个长期主义者的年度计划
  37. 程序员cxuan:坚持并活下去!cxuan 在思否的 2020 年终总结。
  38. 芋头芒果小龙虾再见2020,再见口罩,再见所有的不愉快
  39. thinkwei全面建设小康社会的2020年
  40. Java中文社群大龄程序员10年编程生涯的转型之旅,2020年新的开始
  41. kumfo写在2020年结尾——2020总结
  42. qqxx6661阔别2020 | 我的年度总结
  43. joking_zhang2020 总结 | 张兜兜 - 神奇的一年
  44. ChorChor 的 2020 年度总结 | 2020,再见;2021,你好
  45. 0xBoo二零二零年终总结
  46. 风中有php做的云洪光光的2020年
  47. 陆陆通通「2020总结」一个老程序员的 2020 年总结回顾,2021 年如何变的更牛逼
  48. By无邪2020年度总结
  49. 三掌柜2020年年度关于前端学习与工作的心得体会
  50. Gopalopal 的 2020 年度总结
【50人】(自本篇文章发布至1月31日)参与活动且文章符合要求被收录的征文作者即可获得奖励
1-20 可获得 SegmentFault 思否定制马克杯 + 编程课程 8 折劵(文中列出的课程)
21-50 可获得重启世界限量版手办 + 编程课程 8 折劵(文中列出的课程)
PS:如果同时入选了其他奖项,奖品不重复提供哦,会顺延~

礼品如下:

编程课程8折劵(会在现有的折扣价上再打 8 折):

视频课程
图文课程

实物奖品
image
实物奖品大合影

感谢融云RongCloud、青云QingCloud、京东智联云开发者社区、AWS、ARM中国 等对本次活动的赞助

如何领取奖品?

中奖的小伙伴请扫描下方二维码,添加 SF 思否小姐姐 微信,提供你的礼物邮寄地址和相关快递信息~

PS:临近过年,只能年后给大家发礼品了,大家记得把联系方式发给我
祝大家新年快乐 ~

图片描述

查看原文

赞 12 收藏 0 评论 10

thinkwei 收藏了文章 · 2月1日

Redis 缓存雪崩、击穿、穿透

你知道的越多,你不知道的越多

点赞再看,养成习惯

正文

提到Redis我相信各位在面试,或者实际开发过程中对缓存雪崩穿透击穿也不陌生吧,就算没遇到过但是你肯定听过,那三者到底有什么区别,我们又应该怎么去防止这样的情况发生呢,我们有请下一位受害者。

面试开始

一个大腹便便,穿着格子衬衣的中年男子,拿着一个满是划痕的mac向你走来,看着快秃顶的头发,心想着肯定是尼玛顶级架构师吧!但是我们腹有诗书气自华,虚都不虚。

小伙子我看你的简历上写到了Redis,那么我们直接开门见山,直接怼常见的几个大问题,Redis雪崩了解么?

帅气迷人的面试官您好,我了解的,目前电商首页以及热点数据都会去做缓存 ,一般缓存都是定时任务去刷新,或者是查不到之后去更新的,定时任务刷新就有一个问题。

举个简单的例子:如果所有首页的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩。

我刻意看了下我做过的项目感觉再吊的都不允许这么大的QPS直接打DB去,不过没慢SQL加上分库,大表分表可能还还算能顶,但是跟用了Redis的差距还是很大

同一时间大面积失效,那一瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想想如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,并且对你的产品失去了信心,什么垃圾产品。

面试官摸了摸自己的头发,嗯还不错,那这种情况咋整?你都是怎么去应对的?

处理缓存雪崩简单,在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效,我相信,Redis这点流量还是顶得住的。

setRedis(Key,value,time + Math.random() * 10000);

如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题,不过本渣我在生产环境中操作集群的时候,单个服务都是对应的单个Redis分片,是为了方便数据的管理,但是也同样有了可能会失效这样的弊端,失效时间随机是个好策略。

或者设置热点数据永远不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那你刷下缓存就完事了,不要设置过期时间),电商首页的数据也可以用这个操作,保险。

那你了解缓存穿透和击穿么,可以说说他们跟雪崩的区别么?

嗯,了解,我先说一下缓存穿透吧,缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。

小点的单机系统,基本上用postman就能搞死,比如我自己买的阿里云服务

像这种你如果不对参数做校验,数据库id都是大于0的,我一直用小于0的参数去请求你,每次都能绕开Redis直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了。

至于缓存击穿嘛,这个跟缓存雪崩有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿不同的是缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。

面试官露出欣慰的眼光,那他们分别怎么解决

缓存穿透我会在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等。

这里我想提的一点就是,我们在开发程序的时候都要有一颗“不信任”的心,就是不要相信任何调用方,比如你提供了API接口出去,你有这几个参数,那我觉得作为被调用方,任何可能的参数情况都应该被考虑到,做校验,因为你不相信调用你的人,你不知道他会传什么参数给你。

举个简单的例子,你这个接口是分页查询的,但是你没对分页参数的大小做限制,调用的人万一一口气查 Integer.MAX_VALUE 一次请求就要你几秒,多几个并发你不就挂了么?是公司同事调用还好大不了发现了改掉,但是如果是黑客或者竞争对手呢?在你双十一当天就调你这个接口会发生什么,就不用我说了吧。这是之前的Leader跟我说的,我觉得大家也都应该了解下。

从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null、位置错误、稍后重试这样的值具体取啥问产品,或者看具体的场景,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。

这样可以防止攻击用户反复用同一个id暴力攻击,但是我们要知道正常用户是不会在单秒内发起这么多次请求的,那网关层Nginx本渣我也记得有配置项,可以让运维大大对单个IP每秒访问次数超出阈值的IP都拉黑。

那你还有别的办法么?

还有我记得Redis还有一个高级用法布隆过滤器(Bloom Filter)这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。

那又有小伙伴说了如果黑客有很多个IP同时发起攻击呢?这点我一直也不是很想得通,但是一般级别的黑客没这么多肉鸡,再者正常级别的Redis集群都能抗住这种级别的访问的,小公司我想他们不会感兴趣的。把系统的高可用做好了,集群还是很能顶的。

缓存击穿的话,设置热点数据永远不过期。或者加上互斥锁就能搞定了

作为暖男,代码我肯定帮你们准备好了

面试结束

嗯嗯还不错,三个点都回答得很好,今天也不早了,面试就先到这里,明天你再过来二面我继续问一下你关于Redis集群高可用,主从同步,哨兵等知识点的问题。

晕居然还有下一轮面试!(强行下一期的伏笔哈哈)但是为了offer还是得舔,嗯嗯,好的帅气面试官。

能回答得这么全面这么细节还是忍不住点赞

暗示点赞,每次都看了不点赞,你们想白嫖我么?你们好坏喲,不过我喜欢

总结

我们玩归玩,闹归闹,别拿面试开玩笑。

本文简单的介绍了,Redis雪崩击穿穿透,三者其实都差不多,但是又有一些区别,在面试中其实这是问到缓存必问的,大家不要把三者搞混了,因为缓存雪崩、穿透和击穿,是缓存最大的问题,要么不出现,一旦出现就是致命性的问题,所以面试官一定会问你。

大家一定要理解是怎么发生的,以及是怎么去避免的,发生之后又怎么去抢救,你可以不是知道很深入,但是你不能一点都不去想,面试有时候不一定是对知识面的拷问,或许是对你的态度的拷问,如果你思路清晰,然后知其然还知其所以然那就很赞,还知道怎么预防那来上班吧。

最后暖男我继续给你们做个小的技术总结:

一般避免以上情况发生我们从三个时间段去分析下:

  • 事前:Redis 高可用,主从+哨兵,Redis cluster,避免全盘崩溃。
  • 事中:本地 ehcache 缓存 + Hystrix 限流+降级,避免 MySQL 被打死。
  • 事后:Redis 持久化 RDB+AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

上面的几点我会在吊打系列Redis篇全部讲一下这个月应该可以吧Redis更完,限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?走降级!可以返回一些默认的值,或者友情提示,或者空白的值。

好处:

数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。 只要数据库不死,就是说,对用户来说,3/5 的请求都是可以被处理的。 只要有 3/5 的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。

这个在目前主流的互联网大厂里面是最常见的,你是不是好奇,某明星爆出什么事情,你发现你去微博怎么刷都空白界面,但是有的人又直接进了,你多刷几次也出来了,现在知道了吧,那是做了降级,牺牲部分用户的体验换来服务器的安全,可还行?

敖丙 | 文 【原创】

查看原文

thinkwei 收藏了文章 · 2月1日

Redis 缓存雪崩、击穿、穿透

你知道的越多,你不知道的越多

点赞再看,养成习惯

正文

提到Redis我相信各位在面试,或者实际开发过程中对缓存雪崩穿透击穿也不陌生吧,就算没遇到过但是你肯定听过,那三者到底有什么区别,我们又应该怎么去防止这样的情况发生呢,我们有请下一位受害者。

面试开始

一个大腹便便,穿着格子衬衣的中年男子,拿着一个满是划痕的mac向你走来,看着快秃顶的头发,心想着肯定是尼玛顶级架构师吧!但是我们腹有诗书气自华,虚都不虚。

小伙子我看你的简历上写到了Redis,那么我们直接开门见山,直接怼常见的几个大问题,Redis雪崩了解么?

帅气迷人的面试官您好,我了解的,目前电商首页以及热点数据都会去做缓存 ,一般缓存都是定时任务去刷新,或者是查不到之后去更新的,定时任务刷新就有一个问题。

举个简单的例子:如果所有首页的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩。

我刻意看了下我做过的项目感觉再吊的都不允许这么大的QPS直接打DB去,不过没慢SQL加上分库,大表分表可能还还算能顶,但是跟用了Redis的差距还是很大

同一时间大面积失效,那一瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想想如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,并且对你的产品失去了信心,什么垃圾产品。

面试官摸了摸自己的头发,嗯还不错,那这种情况咋整?你都是怎么去应对的?

处理缓存雪崩简单,在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效,我相信,Redis这点流量还是顶得住的。

setRedis(Key,value,time + Math.random() * 10000);

如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题,不过本渣我在生产环境中操作集群的时候,单个服务都是对应的单个Redis分片,是为了方便数据的管理,但是也同样有了可能会失效这样的弊端,失效时间随机是个好策略。

或者设置热点数据永远不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那你刷下缓存就完事了,不要设置过期时间),电商首页的数据也可以用这个操作,保险。

那你了解缓存穿透和击穿么,可以说说他们跟雪崩的区别么?

嗯,了解,我先说一下缓存穿透吧,缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。

小点的单机系统,基本上用postman就能搞死,比如我自己买的阿里云服务

像这种你如果不对参数做校验,数据库id都是大于0的,我一直用小于0的参数去请求你,每次都能绕开Redis直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了。

至于缓存击穿嘛,这个跟缓存雪崩有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿不同的是缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。

面试官露出欣慰的眼光,那他们分别怎么解决

缓存穿透我会在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等。

这里我想提的一点就是,我们在开发程序的时候都要有一颗“不信任”的心,就是不要相信任何调用方,比如你提供了API接口出去,你有这几个参数,那我觉得作为被调用方,任何可能的参数情况都应该被考虑到,做校验,因为你不相信调用你的人,你不知道他会传什么参数给你。

举个简单的例子,你这个接口是分页查询的,但是你没对分页参数的大小做限制,调用的人万一一口气查 Integer.MAX_VALUE 一次请求就要你几秒,多几个并发你不就挂了么?是公司同事调用还好大不了发现了改掉,但是如果是黑客或者竞争对手呢?在你双十一当天就调你这个接口会发生什么,就不用我说了吧。这是之前的Leader跟我说的,我觉得大家也都应该了解下。

从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null、位置错误、稍后重试这样的值具体取啥问产品,或者看具体的场景,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。

这样可以防止攻击用户反复用同一个id暴力攻击,但是我们要知道正常用户是不会在单秒内发起这么多次请求的,那网关层Nginx本渣我也记得有配置项,可以让运维大大对单个IP每秒访问次数超出阈值的IP都拉黑。

那你还有别的办法么?

还有我记得Redis还有一个高级用法布隆过滤器(Bloom Filter)这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。

那又有小伙伴说了如果黑客有很多个IP同时发起攻击呢?这点我一直也不是很想得通,但是一般级别的黑客没这么多肉鸡,再者正常级别的Redis集群都能抗住这种级别的访问的,小公司我想他们不会感兴趣的。把系统的高可用做好了,集群还是很能顶的。

缓存击穿的话,设置热点数据永远不过期。或者加上互斥锁就能搞定了

作为暖男,代码我肯定帮你们准备好了

面试结束

嗯嗯还不错,三个点都回答得很好,今天也不早了,面试就先到这里,明天你再过来二面我继续问一下你关于Redis集群高可用,主从同步,哨兵等知识点的问题。

晕居然还有下一轮面试!(强行下一期的伏笔哈哈)但是为了offer还是得舔,嗯嗯,好的帅气面试官。

能回答得这么全面这么细节还是忍不住点赞

暗示点赞,每次都看了不点赞,你们想白嫖我么?你们好坏喲,不过我喜欢

总结

我们玩归玩,闹归闹,别拿面试开玩笑。

本文简单的介绍了,Redis雪崩击穿穿透,三者其实都差不多,但是又有一些区别,在面试中其实这是问到缓存必问的,大家不要把三者搞混了,因为缓存雪崩、穿透和击穿,是缓存最大的问题,要么不出现,一旦出现就是致命性的问题,所以面试官一定会问你。

大家一定要理解是怎么发生的,以及是怎么去避免的,发生之后又怎么去抢救,你可以不是知道很深入,但是你不能一点都不去想,面试有时候不一定是对知识面的拷问,或许是对你的态度的拷问,如果你思路清晰,然后知其然还知其所以然那就很赞,还知道怎么预防那来上班吧。

最后暖男我继续给你们做个小的技术总结:

一般避免以上情况发生我们从三个时间段去分析下:

  • 事前:Redis 高可用,主从+哨兵,Redis cluster,避免全盘崩溃。
  • 事中:本地 ehcache 缓存 + Hystrix 限流+降级,避免 MySQL 被打死。
  • 事后:Redis 持久化 RDB+AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

上面的几点我会在吊打系列Redis篇全部讲一下这个月应该可以吧Redis更完,限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?走降级!可以返回一些默认的值,或者友情提示,或者空白的值。

好处:

数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。 只要数据库不死,就是说,对用户来说,3/5 的请求都是可以被处理的。 只要有 3/5 的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。

这个在目前主流的互联网大厂里面是最常见的,你是不是好奇,某明星爆出什么事情,你发现你去微博怎么刷都空白界面,但是有的人又直接进了,你多刷几次也出来了,现在知道了吧,那是做了降级,牺牲部分用户的体验换来服务器的安全,可还行?

敖丙 | 文 【原创】

查看原文

thinkwei 收藏了文章 · 1月20日

macOS使用Homebrew的经验分享

前言

本来想着macOS使用Homebrew对大家没啥难度,之前就分享了一篇介绍homebrew-bundle备份恢复的文章,不过长期使用后还是觉得有必要做一下总结,道理也很简单,越简单越频繁使用的产品就越值得挖掘一些背自己忽视的小技巧,因为如果可以做到每天节省5分钟那么量变可能会成为质变。

更新历史

2019年09月11日 - 更新转载Homebrew 深度应用
2019年09月08日 - 初稿

阅读原文 - https://wsgzao.github.io/post...

扩展阅读

Homebrew

macOS使用homebrew-bundle优雅的备份和恢复软件列表


Homebrew简介

Homebrew 是一款享有盛名的包管理工具,是 macOS 上包管理的事实 (de facto) 标准 。Homebrew 的意思是家酿啤酒。

它的官方 slogan 是 The missing package manager for macOS (or Linux)。Linuxbrew 已经在 Homebrew 1.9 正式合入,成为 Homebrew 的 “一等公民”。

Homebrew 最早的创建者是 Max Howell,目前的主要维护者是 Mike McQuaid。同 Jekyll 等开源项目一样,Homebrew 的核心维护者也是 GitHub 的员工。GitHub 对于员工亲自参加开源项目方面,做得一直不错。

顺带插播一条奇闻逸事:Homebrew 的创始人 Max Howell 活跃在开源社区,目前主要从事 Swift 相关的库开发。他在 2015 年初曾去 Google 面试,因为 “白板” 写算法题「翻转二叉树」失败,愤而发 tweet 讽刺:

Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.

为什么需要Homebrew

对于使用 Unix/Linux 类系统的用户往往都遇到过这些需求:

  • 开源程序是源码分发,需要自己编译,但 ./configure 参数超多,还要解决各种库的依赖
  • 想把软件安装到用户目录,而不是系统目录(这样不需要 root 权限)
  • 自己编译安装了软件,想删除时却不知道在哪里删除和删除哪些文件

各 Linux 发行版为了提升安装软件的体验,大多都提供了官方的包管理器,如 Ubuntu 的 aptitude (apt-get)。而苹果官方没有为 macOS 提供包管理器,市面上最好的解决方案就是 Homebrew。

目前 Homebrew 的中文内容大多以简单入门级教程为主,对于它的各类能力提之甚少,我希望在这里更全面的分享 Homebrew。

Homebrew快速入门

网上基础的教程很多,我这里只简略的介绍下。对于基础功能类的深度用法,推荐这篇 macOS 包管理工具 Homebrew 不完全指南

Homebrew安装

安装

开始安装前需要安装 macOS 命令行工具:

xcode-select —install

或者,在 https://developer.apple.com/d... 下载安装。

然后执行:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

基础功能

# 安装
brew install wget

# 完成安装后可以列出已安装内容
brew list

# 显示可以升级的包
brew outdated

cmake (3.13.4) < 3.14.0
yarn (1.13.0) < 1.15.2
youtube-dl (2019.03.09) < 2019.03.18

# 进行升级
brew upgrade cmake

# 删除
brew uninstall wget

# 安装桌面程序
brew cask install google-chrome

对于 Homebrew-cask 管理桌面程序,这里先不细说,后面会专门讲。

Homebrew 会把软件安装到 /usr/local/Cellar,并且通过软链链接到 /usr/local/bin。我们可以通过 brew unlinkbrew link 删除或创建链接。

名词解释

Homebrew 把软件安装过程中的各种名词都进行了拟物化命名,这些命名挺有意思,但对于大多数英语水平一般的人来说,有不少词汇有些生僻。

英文直译实际含义
formula(e)公式安装包的描述文件,formulae 为复数
cellar地窖安装好后所在的目录
keg小桶具体某个包所在的目录,keg 是 cellar 的子目录
bottle瓶子预先编译好的包,不需要现场下载编译源码,速度会快很多;官方库中的包大多都是通过 bottle 方式安装
tap(插入) 水龙头下载启用某个源
cask木桶安装 macOS native 应用的扩展
bundle描述 Homebrew 依赖的扩展

Homebrew进阶用法

对于 Homebrew,我们很多时候往往都是上来就 brew search 或是 brew install。缺什么安什么,没有充分的应用它的强大能力。

首先,Homebrew 虽为解决控制台程序而生,但它完全有能力(Cask)安装任何桌面软件。它还支持丰富的分类目软件库或第三方库。

除此之外,它还有一个打包安装或备份工具,可以把已安装的软件输出成 Brewfile。迁移到新电脑时,只要根据 Brewfile 运行 Homebrew bundle,就可以一键安装全部控制台、桌面和来自 Mac App Store 的程序(Mac App Store 上的软件通过 mas 支持)。

Tap

Tap 在 Homebrew 中我理解是个动词,指的是启用某个源。实际看了下发现,homebrew-services 和 homebrew-bundle 也已 tap 形式存在,因此可以认为 tap 实际指的应该是扩展(extension)。

Homebrew 默认情况下会自带:

  • homebrew/core
  • homebrew/cask
  • homebrew/services
  • homebrew/bundle

后两者并没有任何公式配方,而只是扩展程序。

除此之外的源,需要通过 brew tap 来启用。如:

brew tap heroku/brew
brew install heroku

Services

Homebrew-services 是 Homebrew 的后台服务程序扩展,它基于 macOS 的 launchctl。后台服务类程序的安装依旧使用 Homebrew,在管理时可以使用 Homebrew-services 进行启动、重启和停止等操作。

brew install mysql
brew services start mysql

Cask

Homebrew-cask 是 Homebrew 的 macOS Native 应用扩展,通过 cask 可以安装各类应用程序。

搜索 Cask 的方法和搜索普通包一样,但安装时需要加上 cask 指令:

brew search google-chrome
brew cask install google-chrome
cask-versions

Homebrew Cask 和 Homebrew 一样,默认库只维护最新版本,但有的时候我们还是需要用旧版的(比如:我只有 Dash 3 的 License,所以需要用 Dash 3 而不是最新的 Dash 4),那就可能需要使用 cask-versions。

brew tap homebrew/cask-versions
brew cask install dash3
cask-fonts

Homebrew 官方的字体源,比如 Mozilla 的开源字体 Fira Code:

brew tap homebrew/cask-fonts
brew cask install font-fira-code

Bundle

Homebrew 不仅仅是一个包管理器,还具有软件依赖管理能力。通过 Homebrew Bundle 可以帮你解决所有软件依赖,包括官方和第三方的 formula 以及 cask,甚至还包括 Mac App Store(简称 mas)中的应用。

Homebrew 默认就安装了 Homebrew Bundle。

我们只需要一个 Brewfile,就可以配置好所有需要的应用。熟悉 Ruby 的人应该不太需要解释,毕竟 Ruby 自己就有 Bundler 这套东西,Brewfile 和 Gemfile 属于对应关系。

如果你的安装列表已经足够 “干净”,那么可以执行 brew bundle dump 来生成现有依赖,输出到 Brewfile

brew bundle dump
cat Brewfile

brew "git"
brew "wget"
brew "mas"
brew "p7zip"
...

如果想自己写也比较容易,Brewfile 是一种简单的 Ruby DSL,写起来比大部分配置文件都简单。只需要掌握一些常用到的命令,主要有 brew, tap, caskmas

这四条命令分别对应:

  • brew install
  • brew tap
  • brew cask install
  • mas install
注:Homebrew 虽然好用,但 Homebrew 并不能管理 MAS「Mac App Store」上的应用软件,在终端上轻松管理「Mac App Store」中应用的神器 mas-cli

命令行类应用:

brew "git"
brew "wget"
brew "vim"

非命令行类:

cask "google-chrome"
cask "alfred"
cask "visual-studio-code"

非官方 Formula 应用:

tap  "homebrew/cask-versions"
brew "dash3"
tap  "homebrew/cask-fonts"
cask "font-source-code-pro"

Mac App Store 上的应用:

mas "WeChat", id: 836500024

因此,维护好 Brewfile 就可以完美解决应用自动化安装,只需要运行:

brew bundle

Homebrew扩展用法

提交Formula

创建并提交一个 Formula 比较容易,官方教程非常详细。这里,我就不做单独介绍了。

自建Tap

Homebrew 除了各种官方维护的源外,还支持自建软件库。默认使用 GitHub,需要以 “homebrew-xxx” 格式命名 Repo。Formula 或 Cask 文件需要存放在 Formula 或 Casks 二级目录中。

比如,Heroku 的自建库在 GitHub 上是 heroku/homebrew-brew。通过 brew tap heroku/brew 就可以获取库里维护的包了。

私有Tap

上面说到,Tap 默认维护在 GitHub,那么当我们想安装一些需要保密的软件时该怎么办呢?

答案是 Tap 支持指定 Git,因此也可以使用内网域名内的 Git:

brew tap yourcompany/brew git@git.yourcompany.com: yourcompany/homebrew-brew.git
brew install inhouse-app

Homebrew Tips

禁用自动升级

Homebrew 自动升级触发概率很高,由于网络等问题,检查更新会很久有时会比较烦。可以通过环境变量禁用自动升级:

HOMEBREW_NO_AUTO_UPDATE=1 brew info mysql

直接安装 Formula

Homebrew 的安装指令并非只支持名字,也可以用文件安装包括网络文件和本地文件。

# 本地
brew install blabla.rb
# 远程
brew install https://blablablabla.com/blabla.rb

安装旧版软件

Homebrew 默认情况下只支持最新版软件安装,有些重要的版本会单独存在。但想安装一些小版本就得自己 DIY 了。

我所知有两种方法:

  1. 在 GitHub 找到 Formula 所在 Repo 中(默认为 homebrew-core)的文件,把文件远程地址复制下来,用 brew install 安装。
  2. 进入 homebrew-core 在 macOS 本地的路径,默认为 /usr/local/Homebrew/Library/Taps/homebrew/homebrew-coregit checkout 到所在 commit,再用 brew pin 锁定这个文件的更新,然后进行安装。

Homebrew常见问题

我遇到的问题大多数是升级macOS Mojave之后产生的,升级前要三思而后行,先备份,先备份,先备份

Homebrew Permissions Denied Issues Solution

sudo chown -R $(whoami) $(brew --prefix)/*

Reference - https://gist.github.com/iraza...

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun.

Reference - https://apple.stackexchange.c...

# The problem is that you are using XCode and you explicit have to agree to the license agreement. So open Terminal, and run the following:

xcode-select --install

# This will download and install xcode developer tools and fix the problem. As a follow on step, you may need to reset the path to Xcode if you have several versions or want the command line tools to run without Xcode.

xcode-select --switch /Applications/Xcode.app
xcode-select --switch /Library/Developer/CommandLineTools

Homebrew国内加速镜像

Homebrew 清华大学镜像使用帮助

加速一切 - 配置国内镜像 - Linux apt/macOS brew/Docker/Python Conda/Maven

参考文章

Max Howell on Twitter: “Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.”

https://github.com/Linuxbrew/brew/issues/612

Formula Cookbook — Homebrew Documentation

Glossary of Homebrew Terms

Formula Cookbook — Homebrew Documentation

在终端上轻松管理「Mac App Store」中应用的神器 mas-cli

Homebrew 深度应用

查看原文

thinkwei 赞了文章 · 1月20日

macOS使用Homebrew的经验分享

前言

本来想着macOS使用Homebrew对大家没啥难度,之前就分享了一篇介绍homebrew-bundle备份恢复的文章,不过长期使用后还是觉得有必要做一下总结,道理也很简单,越简单越频繁使用的产品就越值得挖掘一些背自己忽视的小技巧,因为如果可以做到每天节省5分钟那么量变可能会成为质变。

更新历史

2019年09月11日 - 更新转载Homebrew 深度应用
2019年09月08日 - 初稿

阅读原文 - https://wsgzao.github.io/post...

扩展阅读

Homebrew

macOS使用homebrew-bundle优雅的备份和恢复软件列表


Homebrew简介

Homebrew 是一款享有盛名的包管理工具,是 macOS 上包管理的事实 (de facto) 标准 。Homebrew 的意思是家酿啤酒。

它的官方 slogan 是 The missing package manager for macOS (or Linux)。Linuxbrew 已经在 Homebrew 1.9 正式合入,成为 Homebrew 的 “一等公民”。

Homebrew 最早的创建者是 Max Howell,目前的主要维护者是 Mike McQuaid。同 Jekyll 等开源项目一样,Homebrew 的核心维护者也是 GitHub 的员工。GitHub 对于员工亲自参加开源项目方面,做得一直不错。

顺带插播一条奇闻逸事:Homebrew 的创始人 Max Howell 活跃在开源社区,目前主要从事 Swift 相关的库开发。他在 2015 年初曾去 Google 面试,因为 “白板” 写算法题「翻转二叉树」失败,愤而发 tweet 讽刺:

Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.

为什么需要Homebrew

对于使用 Unix/Linux 类系统的用户往往都遇到过这些需求:

  • 开源程序是源码分发,需要自己编译,但 ./configure 参数超多,还要解决各种库的依赖
  • 想把软件安装到用户目录,而不是系统目录(这样不需要 root 权限)
  • 自己编译安装了软件,想删除时却不知道在哪里删除和删除哪些文件

各 Linux 发行版为了提升安装软件的体验,大多都提供了官方的包管理器,如 Ubuntu 的 aptitude (apt-get)。而苹果官方没有为 macOS 提供包管理器,市面上最好的解决方案就是 Homebrew。

目前 Homebrew 的中文内容大多以简单入门级教程为主,对于它的各类能力提之甚少,我希望在这里更全面的分享 Homebrew。

Homebrew快速入门

网上基础的教程很多,我这里只简略的介绍下。对于基础功能类的深度用法,推荐这篇 macOS 包管理工具 Homebrew 不完全指南

Homebrew安装

安装

开始安装前需要安装 macOS 命令行工具:

xcode-select —install

或者,在 https://developer.apple.com/d... 下载安装。

然后执行:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

基础功能

# 安装
brew install wget

# 完成安装后可以列出已安装内容
brew list

# 显示可以升级的包
brew outdated

cmake (3.13.4) < 3.14.0
yarn (1.13.0) < 1.15.2
youtube-dl (2019.03.09) < 2019.03.18

# 进行升级
brew upgrade cmake

# 删除
brew uninstall wget

# 安装桌面程序
brew cask install google-chrome

对于 Homebrew-cask 管理桌面程序,这里先不细说,后面会专门讲。

Homebrew 会把软件安装到 /usr/local/Cellar,并且通过软链链接到 /usr/local/bin。我们可以通过 brew unlinkbrew link 删除或创建链接。

名词解释

Homebrew 把软件安装过程中的各种名词都进行了拟物化命名,这些命名挺有意思,但对于大多数英语水平一般的人来说,有不少词汇有些生僻。

英文直译实际含义
formula(e)公式安装包的描述文件,formulae 为复数
cellar地窖安装好后所在的目录
keg小桶具体某个包所在的目录,keg 是 cellar 的子目录
bottle瓶子预先编译好的包,不需要现场下载编译源码,速度会快很多;官方库中的包大多都是通过 bottle 方式安装
tap(插入) 水龙头下载启用某个源
cask木桶安装 macOS native 应用的扩展
bundle描述 Homebrew 依赖的扩展

Homebrew进阶用法

对于 Homebrew,我们很多时候往往都是上来就 brew search 或是 brew install。缺什么安什么,没有充分的应用它的强大能力。

首先,Homebrew 虽为解决控制台程序而生,但它完全有能力(Cask)安装任何桌面软件。它还支持丰富的分类目软件库或第三方库。

除此之外,它还有一个打包安装或备份工具,可以把已安装的软件输出成 Brewfile。迁移到新电脑时,只要根据 Brewfile 运行 Homebrew bundle,就可以一键安装全部控制台、桌面和来自 Mac App Store 的程序(Mac App Store 上的软件通过 mas 支持)。

Tap

Tap 在 Homebrew 中我理解是个动词,指的是启用某个源。实际看了下发现,homebrew-services 和 homebrew-bundle 也已 tap 形式存在,因此可以认为 tap 实际指的应该是扩展(extension)。

Homebrew 默认情况下会自带:

  • homebrew/core
  • homebrew/cask
  • homebrew/services
  • homebrew/bundle

后两者并没有任何公式配方,而只是扩展程序。

除此之外的源,需要通过 brew tap 来启用。如:

brew tap heroku/brew
brew install heroku

Services

Homebrew-services 是 Homebrew 的后台服务程序扩展,它基于 macOS 的 launchctl。后台服务类程序的安装依旧使用 Homebrew,在管理时可以使用 Homebrew-services 进行启动、重启和停止等操作。

brew install mysql
brew services start mysql

Cask

Homebrew-cask 是 Homebrew 的 macOS Native 应用扩展,通过 cask 可以安装各类应用程序。

搜索 Cask 的方法和搜索普通包一样,但安装时需要加上 cask 指令:

brew search google-chrome
brew cask install google-chrome
cask-versions

Homebrew Cask 和 Homebrew 一样,默认库只维护最新版本,但有的时候我们还是需要用旧版的(比如:我只有 Dash 3 的 License,所以需要用 Dash 3 而不是最新的 Dash 4),那就可能需要使用 cask-versions。

brew tap homebrew/cask-versions
brew cask install dash3
cask-fonts

Homebrew 官方的字体源,比如 Mozilla 的开源字体 Fira Code:

brew tap homebrew/cask-fonts
brew cask install font-fira-code

Bundle

Homebrew 不仅仅是一个包管理器,还具有软件依赖管理能力。通过 Homebrew Bundle 可以帮你解决所有软件依赖,包括官方和第三方的 formula 以及 cask,甚至还包括 Mac App Store(简称 mas)中的应用。

Homebrew 默认就安装了 Homebrew Bundle。

我们只需要一个 Brewfile,就可以配置好所有需要的应用。熟悉 Ruby 的人应该不太需要解释,毕竟 Ruby 自己就有 Bundler 这套东西,Brewfile 和 Gemfile 属于对应关系。

如果你的安装列表已经足够 “干净”,那么可以执行 brew bundle dump 来生成现有依赖,输出到 Brewfile

brew bundle dump
cat Brewfile

brew "git"
brew "wget"
brew "mas"
brew "p7zip"
...

如果想自己写也比较容易,Brewfile 是一种简单的 Ruby DSL,写起来比大部分配置文件都简单。只需要掌握一些常用到的命令,主要有 brew, tap, caskmas

这四条命令分别对应:

  • brew install
  • brew tap
  • brew cask install
  • mas install
注:Homebrew 虽然好用,但 Homebrew 并不能管理 MAS「Mac App Store」上的应用软件,在终端上轻松管理「Mac App Store」中应用的神器 mas-cli

命令行类应用:

brew "git"
brew "wget"
brew "vim"

非命令行类:

cask "google-chrome"
cask "alfred"
cask "visual-studio-code"

非官方 Formula 应用:

tap  "homebrew/cask-versions"
brew "dash3"
tap  "homebrew/cask-fonts"
cask "font-source-code-pro"

Mac App Store 上的应用:

mas "WeChat", id: 836500024

因此,维护好 Brewfile 就可以完美解决应用自动化安装,只需要运行:

brew bundle

Homebrew扩展用法

提交Formula

创建并提交一个 Formula 比较容易,官方教程非常详细。这里,我就不做单独介绍了。

自建Tap

Homebrew 除了各种官方维护的源外,还支持自建软件库。默认使用 GitHub,需要以 “homebrew-xxx” 格式命名 Repo。Formula 或 Cask 文件需要存放在 Formula 或 Casks 二级目录中。

比如,Heroku 的自建库在 GitHub 上是 heroku/homebrew-brew。通过 brew tap heroku/brew 就可以获取库里维护的包了。

私有Tap

上面说到,Tap 默认维护在 GitHub,那么当我们想安装一些需要保密的软件时该怎么办呢?

答案是 Tap 支持指定 Git,因此也可以使用内网域名内的 Git:

brew tap yourcompany/brew git@git.yourcompany.com: yourcompany/homebrew-brew.git
brew install inhouse-app

Homebrew Tips

禁用自动升级

Homebrew 自动升级触发概率很高,由于网络等问题,检查更新会很久有时会比较烦。可以通过环境变量禁用自动升级:

HOMEBREW_NO_AUTO_UPDATE=1 brew info mysql

直接安装 Formula

Homebrew 的安装指令并非只支持名字,也可以用文件安装包括网络文件和本地文件。

# 本地
brew install blabla.rb
# 远程
brew install https://blablablabla.com/blabla.rb

安装旧版软件

Homebrew 默认情况下只支持最新版软件安装,有些重要的版本会单独存在。但想安装一些小版本就得自己 DIY 了。

我所知有两种方法:

  1. 在 GitHub 找到 Formula 所在 Repo 中(默认为 homebrew-core)的文件,把文件远程地址复制下来,用 brew install 安装。
  2. 进入 homebrew-core 在 macOS 本地的路径,默认为 /usr/local/Homebrew/Library/Taps/homebrew/homebrew-coregit checkout 到所在 commit,再用 brew pin 锁定这个文件的更新,然后进行安装。

Homebrew常见问题

我遇到的问题大多数是升级macOS Mojave之后产生的,升级前要三思而后行,先备份,先备份,先备份

Homebrew Permissions Denied Issues Solution

sudo chown -R $(whoami) $(brew --prefix)/*

Reference - https://gist.github.com/iraza...

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun.

Reference - https://apple.stackexchange.c...

# The problem is that you are using XCode and you explicit have to agree to the license agreement. So open Terminal, and run the following:

xcode-select --install

# This will download and install xcode developer tools and fix the problem. As a follow on step, you may need to reset the path to Xcode if you have several versions or want the command line tools to run without Xcode.

xcode-select --switch /Applications/Xcode.app
xcode-select --switch /Library/Developer/CommandLineTools

Homebrew国内加速镜像

Homebrew 清华大学镜像使用帮助

加速一切 - 配置国内镜像 - Linux apt/macOS brew/Docker/Python Conda/Maven

参考文章

Max Howell on Twitter: “Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.”

https://github.com/Linuxbrew/brew/issues/612

Formula Cookbook — Homebrew Documentation

Glossary of Homebrew Terms

Formula Cookbook — Homebrew Documentation

在终端上轻松管理「Mac App Store」中应用的神器 mas-cli

Homebrew 深度应用

查看原文

赞 6 收藏 5 评论 0

thinkwei 关注了用户 · 1月20日

buildyuan @buildyuan

talk is cheap,show me the code

关注 2

认证与成就

  • 获得 24 次点赞
  • 获得 59 枚徽章 获得 2 枚金徽章, 获得 11 枚银徽章, 获得 46 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-08-15
个人主页被 2.1k 人浏览