Glow 技术团队博客

Glow 技术团队博客

Thoughts, stories and ideas.

一些快捷方式让 kubectl 更好用

一些快捷方式让 kubectl 更好用

本文为同一作者原博客的中文翻译。 分享一些使用 kubectl 时的命令行小工具、技巧。 oh-my-zsh 的 kubectl 插件: 如果你使用 Zsh 和 oh-my-zsh, 这个插件 将会非常有帮助. 在 rc 文件 ~/.zshrc 的这一行 plugins= 处加上 kubectl 即可使用。即使你不用 Zsh,也许也可以找到你的 shell 的对应插件,或者直接把这里的一些 alias 和 functions 定义 加入到你自己的 rc 文件中去。 该插件最有用的部分就是 alias k=kubectl,只需要输入一个字母就可以使用 kubectl 命令。另一个比较有用的是 kca,它会把后面的命令应用到 all-namespaces。 % kca get
  • Xin Zhao
    Xin Zhao

通过Braintree接入PayPal支付的过程工作笔记

目前在国际互联网支付领域,PayPal无疑是占据主导地位的服务商。它拥有大量活跃用户,覆盖面广、处理交易效率高。但直接对接PayPal进行交易也存在一些问题,比如缺乏定制性,无法接入其他后续业务等。PayPal本身的技术文档也过于细节繁杂,每个API的参数都会细致列出,但是缺乏一个简单易用的Guide和Tutorial引导开发者自己选择必要的环节去做定制(提供的demo仅仅适合非常简易的网店购买场景,并不符合我们公司的情况)。我们选择引入Braintree作为技术中间层。Braintree提供灵活的支付网关接口,一方面可以对接PayPal等多种支付渠道,另一方面也可以通过软件化定制的SDK与产品后端对接。Braintree本身也提供简明易懂的文档和图表演示,文档结构清晰,接入的步骤也不多,便于新手快速学习和掌握。 实现整个支付流程需要三个环节: 第一步,从我们公司server获取token来初始化客户端,以此建立和我们公司的定向交易,同时也验证我们公司Braintree账户的有效性;第二步,用户点击支付按钮后填写自己的PayPal账号信息并且授权,这一部分由PayPal的控件来负责
  • Mandy
    Mandy
不想当PM的DEV不是好QA

不想当PM的DEV不是好QA

从我还是一个实习生的时候,我的mentor就告诉我:不会从产品的角度去思考问题,就永远成为不了一个优秀的开发。这句话,我一直铭记于心。 能够单纯从事自己份内的工作,沉浸于技术钻研、设计重构,不断追求代码的简洁和优美,自然是一种令人向往的体验。心无旁骛,不需要纠结各种corner case,不用操心用户的complaints,这是美好的梦想;现实是,作为dev,实现功能的同时,必须考虑方方面面的反馈和影响,也免不了频繁地和PM、QA,乃至PA,打交道。 DEV作为一整条开发流程的中间环节,既要和上游PM、Designer对接,充分了解项目的需求和功能细节;又要和下游的QA、PA沟通,根据实际使用中收集到的反馈,不断精雕细琢,使最终产品达到期望值。因此沟通与协作不仅不可避免,反而是DEV工作中非常重要的组成部分。这与其他人眼中,DEV通常沉默寡言、消极被动的形象大相径庭。对于一些初入职场的DEV新手来说,可能也有类似的误解。 良好的沟通,可以帮助我们的开发工作事半功倍,确保信息的正确传达;因为误解导致的无奈返工,相信各位在工作中已经见过很多,无疑对各方来说都是痛苦的折磨。
  • Mandy
    Mandy
做数据的酿酒师——使用正确的数据

做数据的酿酒师——使用正确的数据

Data matures like wine, applications like fish. ——James Governor 偶然间看到这则关于数据与产品的解读,让笔者眼前一亮,对其的理解应该是见仁见智,笔者更倾向于这样诠释:成熟的数据像是美酒,并且愈久愈醇,也更有价值,但也许打开的时候才会发现由于数据存储不当而不小心变成了醋。而APP像是鱼,小鱼未来可期,需要悉心呵护才能成长;成鱼生机勃勃,但是年龄越大,往往会到达它的成长极限;鱼群需要繁衍新生命来延续,APP也需要更新迭代才能达到良性循环。 作为一个专注于女性生理健康领域的公司,Glow拥有4款针对女性不同生理阶段的APP产品,从第一次月经到第一次拥有小Baby,女性往往有太多对“第一次”的无所适从,Glow的产品在女性最重要的生理阶段,帮助女性记录相关生理数据来熟悉自己和宝宝的身体状况。 同样,Glow也把数据作为产品决策的主要驱动力。用户借助在Glow APP上记录的数据来调整生活、饮食等节奏来达到期望的需求,而Glow也致力于通过用户行为数据调优自身产品,从而给予用户更好的体验,也让产品自身处于更健康的状
重构推送服务

重构推送服务

最近对业务里发送 apple APNS, google FCM 部分的代码进行了重构, 抽出了一个单独的 service, 本文记录下过程. 存在的问题 我们有好几个 mobile app, 每个 app 会有一套对应的 server 端 service 做业务逻辑, 因为历史原因, 每个 service 里面其实有很多重复代码, 大多只是一些配置和错误处理上有差异. 给 app 发推送是个典型, 原来的做法是当要发推送的时候, 往 python 的 celery 队列里扔一个 task, 由 celery 异步得去发. 有如下问题: * celery 性能不佳, worker class 用的是 gevent, 但在高峰时候任务队列里还是有大量 pending, 代码上之前做过多次优化, 但收效甚微. * 当
  • Will Xu
android

LiveData基础使用方式+工作原理(上篇)

引入androidx后,ViewModel+LiveData搭配Activity/Fragment渐渐成为大家喜爱(习惯)的UI制作方式。 总体来说,这套模式的容易学习,使用也方便,但如果没有详细了解其背后的工作机制,也很容易错误使用造成bug。 在此将分享相关architecture component背后原理,将实际开发中遇到的问题和错误总结一些good practice points,以供参考。 这篇文章主要探讨LiveData的 工作原理 和 基本使用方式。 How it works: * LiveData::setValue VS LiveData::postValue * LiveData::observe(lifecycleOwner, observer) Good Practice Points: * Activity观察LiveData,在onCreate注册观察,livedata.observe(this, Observer{}) * Fragment观察LiveData,在onCreateView/onViewCreated/onActiv

用 Swift 解读 React/React Native: Part 1 - React Element & React Component

React & React Native 不只是一种框架,它更是一种思维方式和方法论。 Glow 使用 React Native 至今一年半有余,项目里也有越来越多的组件被重构成 React Native。在使用 React Native 开发的过程中,我们对 React 和 React Native 本身的思想、架构也有了越来越深入的理解。而这些思想又开始逐渐反作用到 Native 的开发,影响着我们在其他 Native 组件开发过程中的架构选择和实现思路,促使我们重新审视 Native 的开发方式。 通过这个系列的文章,我们想把从 React 和 React Native 中所学,总结成一些有用的经验,为团队将来无论是 React Native 还是 Native 的开发提供有价值的指导。更长远的,我们希望基于这些经验构建一个新的 Native
  • Allen
    Allen

使用 Apollo Client 快速构建一个支持 GraphQL 的 React App

这篇文章主要介绍 GraphQL 在 Client 的使用,为了方便,本文会直接使用 React 创建一个 Web demo 去介绍 Apollo 在 React 中的使用方法,当然在 ReactNative 中用法几乎一模一样。Apollo Client 是一个 GraphQL Client Library ,Apollo Client (以下简称 Apollo) 可以让我们很方便的去和 GraphQL server 通信。 为什么要使用 GraphQL Client Library 你当然可以自己用 Http 去构造一个 GraphQL 请求,然后自己去处理网络问题,以及数据的缓存问题等等,这样我们就需要自己去处理很多业务逻辑以外的事情,而一个优秀的 GraphQL Client Library 可以帮助我们解决以下的一些问题
  • Ray Pan

从 python2.7 迁移到 python3.6

python2.7 会在 2020 年停止维护, 很多第三方包也在去掉对 python2.7 的支持, 最近终于完成了内部代码向 python3 的迁移, 整个过程挺繁琐的, 记录一下. 总共需要迁移的代码大概有 50w 行(cloc 计算, 去注释空行), 包括业务代码 + ETL + data analysis... 前后花了3个月. 做之前确保已读过官方的 migration guide: https://docs.python.org/3/howto/pyporting.html 我的大致步骤: 1. 清查依赖包, 不支持 python3 的 lib 寻找替代品(常用 lib 基本都没问题). 2. 将现有代码转写成 py2/
  • Will Xu
用 GraphQL 快速搭建服务端 API
GraphQL

用 GraphQL 快速搭建服务端 API

Glow 从今年 4 月开始为中国的产品「共乐孕」app 的用户开发社区功能,虽然在之前美国的社区的类似的功能都进行过实现,但我们仍然决定要在这次中国的社区产品开发中尝试一些新东西。其中就包括 GraphQL 。 今天的文章中会简单介绍下 GraphQL 和我们在服务器端使用的第三方库-- Graphene-Python, 以及我们选择这个技术的原因。并通过一些简单的例子展现如何快速上手 GraphQL 。 GraphQL 的介绍 什么是 GraphQL 简单来说,GraphQL 是一种查询语言,它被设计出来的初衷是用于提供 API。 与 RESTful 设计不同,GraphQL 一般仅暴露出一个接口供使用,而具体一个请求中需要什么数据,数据怎么样组织完全由 API 的使用者(客户端)来指定。 当然,哪些数据可以被查询,数据的类型是怎么样的,则是由服务端给定的。 指定的方式就是传入一段关于想要的结果(或操作)的描述,服务端保证返回符合要求的结果或报错。 这篇文章不是重点介绍 GraphQL 本身,就不展开讲了,
  • Xin Zhao
    Xin Zhao
react-native

如何自动化测试 React Native 项目 (下篇) - 单元测试

原创发布于 tech.glowing.com。 接着上篇的内容, 这篇文章会详细的介绍在 Glow 我们如何写单元测试, 以及在 React Native 中各个模块单元测试的详细实现方式。 单元测试工具 - Jest & Enzyme   Jest - Facebook Jest 是 Facebook 开源的 Javascript 测试框架,提供了许多好用的 API,先介绍下主要的优点: * 自带 snapshot 测试,让UI测试简单有效 * 几乎 0 配置,自带各种功能。 相比其他单元测试:karma (test runner) + mocha (test framework) + chai (assertion) + sinon (test spy) + ... * 并行执行测试 case
react-native

如何自动化测试 React Native 项目 (上篇) - 核心思想与E2E自动化

原创发布于 tech.glowing.com。 React Native (RN) 是 Facebook 开源的跨平台应用开发框架,由于 RN 提供的高效直观的跨平台开发模式和不错的性能,我们在开发 Glow 的中文 App - 共乐孕的时候选择了以 RN 为主要框架进行开发。 随着开发模式的逐渐成熟,对RN项目的自动化测试也在不断探索中慢慢完善, 最终选择了 Detox (by Wix) 做 E2E 自动化测试, Jest (FaceBook) + Enzyme (Airbnb) 做集成测试和单元测试。 在这篇文章中我会介绍一下我对 React Native 项目自动化测试的核心想法以及自动化测试中 E2E 部分的具体实现。在 如何自动化测试 React Native 项目 (下篇) 中会详细介绍单元测试的具体实现方法。 核心思想 先介绍一下对自动化测试的思考和对E2E,

在线查询系统性能优化

背景 在最近的一个项目是一个后台管理工具,WEB端需要根据后端录入的数据,显示一个庞大的表格。主要的几点需求如下: 1. 每条记录包含多个字段,都需要显示在WEB端界面上 2. 其中有些字段并不能通过数据库查询直接得出,需要另外计算得出 3. 支持设置过滤条件和按字段排序 4. 需求变化很快,字段可能随时调整 对此,后端为了整体解决,会把查询得到的所有记录都合并到一起作计算,得到包含所有字段的完整数据。有了完整的数据,之后的过滤和排序就相对容易实现了。 问题 这种设计在项目初期的确对快速变化的需求表现出了良好的应变能力。然而随着数据量的增加,该方案也出现了明显的性能问题,经分析发现主要的问题出在以下几个方面: 1. 随着数据量增加,对所有记录做计算越来越耗时 2. 因为数据量的关系,从数据库服务器取出记录的过程本身也很耗时 解决这两个问题的根本都是是减少数据量。很明显,不符合过滤条件的记录没有必要传输到后端服务器上,也没有必要做字段计算。如果可以提前得到甚至缩小符合过滤条件的记录ID,可以大大加速整个过程。 索引表 针对前端特殊的展示
  • Bood
    Bood

Glow data infrastructure 的演化

Glow 一向是一个 data driven 做决策的公司,稳定高效的平台是必不可少的支撑, 本文总结几年里公司 data infrastructure 的演进过程. 结合业务特点做技术选型和实现时候的几个原则: 1. real time 分析的需求不高,时间 delta 控制在1 小时以内可接受 . 2. 支持快速的交互式查询. 3. 底层平台尽量选择 AWS 托管服务, 减少维护成本. 4. 遇到故障, 数据可以 delay 但不能丢. 5. 可回溯历史数据. 6. 成本可控. 用到的 AWS 服务: * 数据存储和查询: S3, Redshift (spectrum), Athena * ETL: DMS, EMR, Kinesis, Firehose, Lambda 开源软件:
  • Will Xu
data-visualization

数据可视化的开源方案: Superset vs Redash vs Metabase (二)

在上篇结尾处我提到“如果现在让我重新选择,我会使用哪个可视化工具?”我的答案是 Redash,原因主要不是功能层面,而是技术层面。本篇就从项目关注度与活跃度,项目的技术架构,源代码的规模与质量,这三个方面来比较一下 Superset,Redash 与 Metabase。 关注度与活跃度 看一个项目在 Github 上的星数,是评判一个项目成熟度最快速的方法。**那除了星数以外,项目的 Github 页面上还有什么重要信息呢?这里我建议大家去看一看项目的 Insights。**首先我们来看 Superset 最近一个月的活跃度 这张图告诉我们以下几个信息 * 这个项目最近一个月有 53 个提交,说明项目仍在积极开发中。图中显示项目在最近一个月有新增 21 万行代码,这主要是因为提交了一个巨大的地理数据文件,去掉这个文件之后,实际新增的代码行数大约为 2000 行。 * 从新增和处理的 Issue 与 PR 来看,项目的社区很活跃,项目开发者也在积极解决问题。 从短期指标来看,
react-native

如何实现 React Native 里的页面导航系统

React Native 中的页面导航和跳转一直是一个让人头疼的问题,其实社区里也已经有各种实现,比如 react-navigation,wix/react-native-navigation,LeoLeBras/react-router-navigation,airbnb/native-navigation,如你所见,react native navigation 三个单词各种排列组合基本上都有了,所以从这些 library 里挑一个合适的同样更让人头疼。 我们在新起的项目中决定用纯 React Native 实现,以尽量减少对 native 的依赖,并且避免因 hybrid app 中 native 页面的层次结构(iOS 中 view controllers,Android 中 activities)在 React 侧不可知、不可控带来的状态管理问题。因此区别于在 React Native 在 Glow 的实践
  • Allen
    Allen
data-visualization

数据可视化的开源方案: Superset vs Redash vs Metabase (一)

人是视觉动物,要用数据把一个故事讲活,图表是必不可少的。如果你经常看到做数据分析同事,在SQL客户端里执行完查询,把结果复制/粘贴到Excel里再做成图表,那说明你的公司缺少一个可靠的数据可视化平台。数据可视化是Business Intelligence(简称BI)中的核心功能,有许多成熟的商用解决方案,如老牌的Tableau, Qilk,新生代的Looker,国内的FineBI等等。不过对于许多小公司来说,这些服务的License费用是一笔不小的开销,且有一种“杀鸡用牛刀”的感觉。那在开源软件如此发达的今天,在数据可视化方面,有什么靠谱的方案可以选择呢?今天给大家介绍三个比较知名的项目,分别是Superset, Redash和Metabase。前两个我都在产生环境中实际使用过,在本文中会重点介绍。Metabase我只是试玩了一下,但我觉得这是一个非常有想法的项目,所以也会和大家聊聊我对它的看法。 选择一个称手的工具,功能上能满足我的需求肯定是首要的。就先从功能需求讲起,我们的数据仓库用的是Amazon Redshift(如果你没听过Redshift,就把它看作是为大数据优化过的P

DynamoDB

DynamoDB 是 AWS 的托管 NoSQL 数据库,可以当作简单的 KV 数据库使用,也可以作为文档数据库使用. Data model 组织数据的单位是 table, 每张 table 必须设置 primary key, 可以设置可选的 sort key 来做索引. 每条数据记作一个 item, 每个 item 含有一个或多个 attribute, 其中必须包括 primary key. attribute 对应的 value 支持以下几种类型: * Number, 由于 DynamoDB 的传输协议是 http + json, 为了跨语言的兼容性, number 一律会被转成 string 传输. * Binary, 用来表示任意的二进制数据,会用
  • Will Xu

使用 Redshift Spectrum 查询 S3 数据

通常使用 redshift 做数据仓库的时候要做大量的 ETL 工作,一般流程是把各种来源的数据捣鼓捣鼓丢到 S3 上去,再从 S3 倒腾进 redshift. 如果你有大量的历史数据要导进 redshift,这个过程就会很痛苦,redshift 对一次倒入大量数据并不友好,你要分批来做。 今年4月的时候, redshift 发布了一个新功能 spectrum, 可以从 redshift 里直接查询 s3 上的结构化数据。最近把部分数据仓库直接迁移到了 spectrum, 正好来讲讲。 动机 Glow 的数据仓库建在 redshift 上, 又分成了两个集群,一个 ssd 的集群存放最近 4 个月的数据,供产品分析,metrics report, debug 等等 adhoc 的查询。4个月之前的数据存放在一个 hdd
  • Will Xu
python

Python web 应用性能调优

为了快速上线,早期很多代码基本是怎么方便怎么来,这样就留下了很多隐患,性能也不是很理想,python 因为 GIL 的原因,在性能上有天然劣势,即使用了 gevent/eventlet 这种协程方案,也很容易因为耗时的 CPU 操作阻塞住整个进程。前阵子对基础代码做了些重构,效果显著,记录一些。 设定目标: * 性能提高了,最直接的效果当然是能用更少的机器处理相同流量,目标是关闭 20% 的 stateless webserver. * 尽量在框架代码上做改动,不动业务逻辑代码。 * 低风险 (历史经验告诉我们,动态一时爽,重构火葬场....) 治标 常见场景是大家开开心心做完一个 feature, sandbox 测试也没啥问题,上线了,结果 server load 飙升,各种 timeout 都来了,要么 rollback 代码,要么加机器。
  • Will Xu
android

在 Android 中集成 React Native 的经验分享

在之前的一篇博客中,Allen已经为大家介绍了React Native在Glow的应用以及大体架构。由于React Native库本身的一些原因,其在Android的成熟度远不及iOS,因此也给在Android的应用带来了更多的挑战。 在本文中,给大家分享一下在Android平台上集成React Native的过程中碰到的一些问题和解决办法。 64位支持 目前React Native的二进制库还不支持64位,而Android并不支持32位和64位二进制库的混合加载(详见Mixing 32- and 64-bit Dependencies in Android)。 因此如果应用中已经包含了64位的二进制库,必须用abiFilters去掉64位二进制库。 ndk { abiFilters "armeabi", "mips", "armeabi-v7a", "x86" } React Native社区也在努力解决这一问题(React Native for Android is incompatible with 3rd-party 64-bit librar
  • Bood
    Bood

React Native 在 Glow 的实践

1. 为什么使用 React Native 在最近发布的 Eve v2.8 里,我们用 React Native 重构了几乎整个 Community。本文记录了 React Native 在 Glow 的实践经验,并主要从 iOS 角度展开一些细节实现。但本文不会涉及太多 React Native 的入门知识,如果你还没有接触过 React Native,推荐先阅读官方文档和 React Native Express。 使用 React Native 主要原因: * 在 JSPatch 和 Rollout.io 被 Apple 封杀以后,需要一种方法热修复 Live Bug * 可以通过热更新的方式发布新的功能或者修改
  • Allen
    Allen
Glow Android 优化实践
android

Glow Android 优化实践

了解 Glow 的朋友应该知道,我们主营四款 App,分别是Eve、Glow、Nuture和Baby。作为创业公司,我们的四款 App 都处于高速开发中,平均每个 Android App 由两人负责开发,包括 Android 和 Server 开发,在满足 PM 各种需求的同时,我们的 session crash free 率保持不低于 99.8%,其中两款 App 接近 100%。 本文将对 Glow 当前 Android App 中对现有工具的探索及优化进行讲解,希望对读者有所启发。 整体结构概览 下面是 Glow Android 端的大体结构: 我们有四个 Android App,
python

Python profiling

Profiling(性能调试)是我一直很感兴趣的一个话题,之前给大家介绍过Datadog这个工具,今天我们来看看Python语言中有哪些方法来做Profiling。 Poorman's Profiler 最基础的就是使用time.time()来计时,这个方法简单有效,也许所有写过Python代码的人都用过。我们可以创建一个decorator使它用起来更方便。 import time import logging import functools def simple_profiling(func): @wraps.functools(func) def wrapped(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) time_spent = time.time() - start_time fullname = '{}.{}'.format(func.