少湖说 | 科技自媒体

互联网,科技,数码,鸿蒙

使用

  • 手机号参数对11位大陆手机号兼容
  • 支持国际手机号,请使用形如(加号)(地区编码)(一个空格)(手机号)的手机格式,例如
地区 合法格式
中国大陆 18682300424
中国大陆 +86 18682300424
美国 +1 2067925640
加拿大 +1 12042345678
英国 +44 7400123456
澳大利亚 +61 412345678

所以手机格式为:以加号开头,前面是地区区号,后面是手机号码,中间保留一个空格

  • 如果国际手机号出现在URL中,请对手机号进行编码(urlencode)

存储和处理手机号码

  • 地区编号和手机号应当分开存储
  • 增加对原11位手机号的兼容性(例如默认自动添加+86前缀)
  • 存储用户信息时,需要将phonecountry_code两个信息分别存储

验证和格式化手机号

  • 使用类库https://github.com/googlei18n/libphonenumber 或者其他语言的实现: https://github.com/googlei18n/libphonenumber#third-party-ports

使用国际手机号测试

  • 搜索可以在线接收短信验证码的平台
  • 在线接收短信验证码,进行后续测试
  • 验证码接收网站参考网址:
  • http://receive-sms.com/
  • https://tieba.baidu.com/p/3752380669
  • http://uuxn.com/seven-recerve-sms-online-free-phone
  • http://www.mfwu.net/receive-sms.html

简介

Kong 是一个微服务API网关。

Kong是一个云原生,快速,可扩展和分布式微服务抽象层(也称为API网关,API中间件或在某些情况下为Service Mesh)。
作为2015年的开源项目,其核心价值在于高性能和可扩展性。
Kong积极维护,广泛应用于从创业公司到Global 5000以及政府组织等公司的生产。

Konga 是一个用于管理网关Kong的管理端,通过它可以方便的进网关进行管理配置。

使用网关能解决很多问题:

  1. 解决端口和域名问题,代理后消除端口,将域名映射到端口,将服务映射成目录
  2. 微服务代理,将微服务置于内网,统一由网关代理
  3. 授权,可以配置授权管理,主要用于API授权
  4. 负载均衡,可以增强高访问量下的可用性,解决部署时的服务中断问题

本文主要讲述使用 Konga 对 Kong 进行网关管理配置

安装

安装过程具体请参考官网文档,如果使用docker安装 Kong 和 Konga,可以参考 配置docker-compose

配置反向代理

在 APIS 一栏,点击 ADD NEW API 按钮,添加一个代理:

  • 其中,Name 为显示名称,可任意填写;
  • Hosts 为所要使用的域名,如果不填写,则使用网关绑定的域名;如果填写,则可通过该域名访问;
  • Uris 为访问路径,如果需要将某个服务映射为一个目录,则此处需要配置;
  • Upstream URL 为上游地址,即微服务实际地址,另外可将微服务置于内网,此处即为内网地址。

需要注意的是,如果页面中有301/302跳转,需要将 Preserve Host 勾选,以保证跳转后,header中携带的 Location 中的域名为代理后的域名,否则会出现实际域名/内网域名,造成混乱,甚至暴露微服务地址

示例一:普通反向代理

配置项 内容 说明
Name dashboard 只是为了方便识别
Hosts dashboard.xxx.com 绑定的域名,类似于vhosts
Uris / 绑定目录
Methods 请求方法,默认不填
Upstream URL http://192.168.0.2:8080 实际微服务地址,建议使用内网ip, 并将该服务屏蔽外网访问
Strip uri YES
Preserve Host YES 转发时保留域名,处理301问题
Https only YES 如果不使用https,不勾选

配置负载均衡

需要注意的是,如果要使用负载均衡,需要配置 上游 (UPSTREAMS)。

在 UPSTREAMS 一栏,点击添加,Name 为一个域名形式的上游名称,如 dashboard.upstream.xxx.com, 添加完后,点击详情里面的Targets,添加一个目标,
Target 为实际的微服务地址,如 192.168.0.1:8080, 注意这里不写http协议,只写ip或域名。

一个 UPSTREAMS 可以配置多个 Targets, 针对每个 Targets 设置不同的 Weight,即实现了负载均衡。

示例二:负载均衡

UPSTREAMS 配置

配置项 内容 说明
Name coupon.api.foundation.com 类域名的别名

Targets 配置

配置项 内容 说明
Target 192.168.0.2:8001 微服务1的地址(建议使用内网)
WEIGHT 100 权重

Targets2 配置

配置项 内容 说明
Target 192.168.0.3:8001 微服务1的地址
WEIGHT 100 权重

Apis 配置

配置项 内容 说明
Name coupon 名称,任意
Hosts 留空使用网关默认的域名,如 api.xxx.com
Uris /coupon 通过 api.xxx.com/coupon 访问该服务
Methods 留空不限制
Upstream URL http://coupon.api.foundation.com/api/ 这里为配置的 UPSTREAMS 里的 Name
Strip uri YES
Preserve Host YES
Https only YES 如果不使用https,不勾选

参考文档

使用Taro和Typescript进行小程序开发

使用指南

在使用 taro 生成 Typescript 模板以后,需要做以下修改:

配置 .eslintrc

  • 加入 "no-undef": 0, 以解决变量undefined的问题
  • 加入 "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }] 以解决 JSX not allowed in files with extension '.tsx

增加配置文件

  • tsconfig.json
  • tslint 文件

增加依赖库

  • yarn add –dev tslint
  • yarn add –dev tslint-react
  • yarn add –dev ptypescript-eslint-parser

开始使用

1
2
3

yarn install

代码静态检查

1
2
yarn run lint

参考文档

2020 更新

微信出了 miniprogram-ci ,可以通过命令行调用,故而改用改方案, 见 [GitLab-CI微信小程序进行持续集成和持续部署2]

问题缘由

在微信小程序开发中,先要在本地使用微信开发者工具进行调试,如果需要在线测试,则需要将编译好的代码上传。
目前,只能通过微信开发者工具手动点击上传,而该过程无法与持续集成/持续部署结合在一起,本文就是为了解决能够实现自动化和持续部署的难题

实现原理

微信开发者工具,提供了HTTP调用方式,其中就包括上传和自动化测试的命令,我们可以通过脚本实现自动化集成

步骤

安装并配置 GitLab Runner

这部分文档在 Install GitLab Runner on macOS

安装

首先需要在本机上安装 GitLab Runner, 由于微信开发者工具只提供了 mac 和 windows 版本,所以目前只能在这两种系统上实现持续集成,本文讲述在 mac 的具体实现, windows 上的实现与此类似,只是相关命令和路径需要做些变更

注册 GitLab Runner

1
2
gitlab-runner register

注意,注册时没有sudo, 因为需要使用用户模式来使用,而非系统模式

注册时,将本机添加上了 mac 标签, 运行模式为shell,这样可以在部署时,指定运行环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://xxxxxx.com/
Please enter the gitlab-ci token for this runner:
xxxxxx
Please enter the gitlab-ci description for this runner:
[xxx.com]: macbook.home
Please enter the gitlab-ci tags for this runner (comma separated):
mac,shell
Whether to run untagged builds [true/false]:
[false]: true
Whether to lock the Runner to current project [true/false]:
[true]: false
Registering runner... succeeded runner=Gd3NhK2t
Please enter the executor: docker-ssh, virtualbox, docker+machine, docker-ssh+machine, docker, parallels, shell, ssh, kubernetes:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

运行服务

1
2
3
4
cd ~
gitlab-runner install
gitlab-runner start

编写 .gitlab-ci.yml

在此之前,你需要对GitLab-CI有一定的掌握,这部分资料参考下方的相关文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
image: node:alpine

before_script:
- export APP_ENV=testing
- yarn config set registry 'https://registry.npm.taobao.org'
stages:
- build
- deploy

variables:
NPM_CONFIG_CACHE: "/cache/npm"
YARN_CACHE_FOLDER: "/cache/yarn"
DOCKER_DRIVER: overlay2
build-package:
stage: build
dependencies: []
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- node_modules
script:
- if [ ! -d "node_modules" ]; then
- yarn install --cache-folder /cache/yarn
- fi
- yarn build
- cp deploy/project.config.json ./dist/project.config.json
artifacts:
name: "wxpkg-dlkhgl-$CI_COMMIT_TAG"
untracked: false
paths:
- dist
only:
- tags
tags:
- docker
deploy:
stage: deploy
dependencies:
- build-package
variables:
GIT_STRATEGY: none
before_script: []
script:
# 获取HTTP服务的端口, 该端口是不固定的
# - PORT=`cat ~/Library/Application\ Support/微信web开发者工具/Default/.ide`
# 调用上传的API
# - curl http://127.0.0.1:$PORT/upload\?projectpath\=$PWD/dist\&version\=$CI_COMMIT_TAG\&desc\=audo-deploy
# 以下改用命令行替代旧的 HTTP 调用方式
- /Applications/wechatwebdevtools.app/Contents/MacOS/cli -u $CI_COMMIT_TAG@/$PWD/dist --upload-desc "aoto deploy"
only:
- tags
tags:
- mac

注意,deploy/project.config.json 文件为 project.config.json的副本,但其他的 projectname 不同,这样做是为了解决 已存在相同 AppID 和 projectname 的项目(路径),请修改后重试的问题,这是因为,同一台电脑上,微信开发者工具不能有两个同名的项目

另外注意,在运行自动部署时,微信开发者工具必须打开,且为登录状态

相关文档

起因

前两天收到跨境电商事业部同事发来的一个需求,说有一个表格,里面只有产品ID和其他一些信息,但是没有其他信息,诸如产品中文名和发货地,这些信息需要通过调取API获得。希望我们帮忙导出合并到Excel中

分析及实现

  • 首先需要读取Excel中,每个产品的ID
  • 然后调用产品查询API,该API通过GET+ID参数方式进行查询
  • 查询到信息后,将需要的信息追加到对应行的后面列中

openpyxl

Python 中操作 Excel 的库有许多,例如 xlrd、xlwt、xlsxwriter、openpyxl 等,openpyxl是其中一个,该库主要有几个特点:支持xlsx,支持对现有文档读写,被Python-Excel优先推荐。
几经对比调研,最终选择 openpyxl。

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 打开excel
wb = load_workbook('files/file.xlsx')
# 拿到打开的sheet
sheet = wb.active
for index in range(0, sheet.max_row):
# load_data 通过requests调用API方法,拿到name和ship_from
name, ship_from = load_data(sheet['A' + str(index + 1)].value)
# 产品中文名称
sheet['D' + str(index + 1)] = name
# 发货地信息
sheet['E' + str(index + 1)] = ship_from
print("同步第" + str(index + 1) + "行")
# 将数据保存到另外一表格中,注意也可以保存到原来表格中
wb.save("files/file-export.xlsx")

在上述代码中,首先加载原始文件files/file.xlsx,然后对默认sheet进行行遍历,每一行第一列An代表产品ID,
load_data方法通过调用API, 查询到该产品的中文名称和发货地,然后再写入后面的列中,如Dn和En

最后全部遍历完后,再保存表格,这样整个需求就实现了

PHP运行环境镜像构建

PHP7中访问SqlServer需要安装sqlsrv 和 pdo_sqlsrv,在此之前需要安装一此必备依赖,如msodbcsql 和 unixodbc-dev,由于SqlServer暂时不支持alpine,所以选择jessie,尽量使镜像保持最小,构建脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FROM php:7.1-fpm-jessie

ENV ACCEPT_EULA=Y

# Microsoft SQL Server Prerequisites
RUN apt-get update \
&& curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
&& curl https://packages.microsoft.com/config/debian/8/prod.list \
> /etc/apt/sources.list.d/mssql-release.list \
&& apt-get install -y --no-install-recommends \
locales \
apt-transport-https \
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
&& locale-gen \
&& apt-get update \
&& apt-get -y --no-install-recommends install msodbcsql unixodbc-dev

RUN docker-php-ext-install mbstring \
&& pecl install sqlsrv pdo_sqlsrv \
&& docker-php-ext-enable sqlsrv pdo_sqlsrv

启动本地开发需要的SqlServer服务

由于微软官方提供的SqlServer镜像,无法通过环境变量配置的方便创建数据库,故选择mcmoe/mssqldocker镜像,

使用docker-compose配置方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3.2'

services:
db:
build: .
image: mcmoe/mssqldocker
environment:
ACCEPT_EULA: Y
SA_PASSWORD: 2astazeY
MSSQL_DB: dev
MSSQL_USER: Kobeissi
MSSQL_PASSWORD: 7ellowEl7akey
ports:
- "1433:1433"
container_name: mssqldev

需要注意的是,MSSQL密码(即上面的SA_PASSWORD和MSSQL_PASSWORD)必须至少8个字符长,包含大写,小写和数字,否则数据库会创建失败

连接访问数据库

在程序中配置数据库的地方,配置DSN如下

1
2
sqlsrv:Server=mssql;Database=dev

sqlsrv 为驱动名称

注:如果是使用Yii2框架,可以使用我构建好的镜像:zacksleo/php:7.1-fpm-mssql

需求

团队使用React开发了一套前端页面, 为了方便协作和部署, 使用 EsLint 进行代码格式审查, 同时进行持续集成和部署, 提高开发效率

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
image: zacksleo/node

before_script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" > ~/deploy.key
- chmod 0600 ~/deploy.key
- ssh-add ~/deploy.key
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- export APP_ENV=testing
- yarn config set registry 'https://registry.npm.taobao.org'
stages:
- prepare
- test
- build
- deploy

variables:
COMPOSER_CACHE_DIR: "/cache/composer"
DOCKER_DRIVER: overlay2
build-cache:
stage: prepare
script:
- yarn install --cache-folder /cache/yarn
cache:
key: "$CI_COMMIT_REF_NAME"
paths:
- node_modules
except:
- docs
- tags
when: manual
eslint:
stage: test
dependencies: []
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- node_modules
script:
- if [ ! -d "node_modules" ]; then
- yarn install --cache-folder /cache/yarn
- fi
- yarn eslint ./
except:
- docs
- develop
- master
- tags
build-check:
stage: test
dependencies: []
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- node_modules
script:
- if [ ! -d "node_modules" ]; then
- yarn install --cache-folder /cache/yarn
- fi
- yarn build
except:
- docs
- develop
- master
- tags
build-package:
stage: test
script:
- if [ ! -d "node_modules" ]; then
- yarn install --cache-folder /cache/yarn
- fi
- if [ $CI_COMMIT_TAG ];then
- cp deploy/production/.env .env
- fi
- yarn build
dependencies: []
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- node_modules
artifacts:
name: "build"
untracked: false
expire_in: 60 mins
paths:
- build
except:
- docs
only:
- develop
- master
- tags
production-image:
stage: build
image: docker:latest
dependencies:
- build-package
before_script: []
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
- docker rmi $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
only:
- tags
production-server:
stage: deploy
dependencies: []
cache: {}
script:
- cd deploy/production
- rsync -rtvhze ssh . root@$DEPLOY_SERVER:/data/$CI_PROJECT_NAME --stats
- ssh root@$DEPLOY_SERVER "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY"
- ssh root@$DEPLOY_SERVER "export COMPOSE_HTTP_TIMEOUT=120 && export DOCKER_CLIENT_TIMEOUT=120 && echo -e '\nTAG=$CI_COMMIT_TAG' >> .env && cd /data/$CI_PROJECT_NAME && docker-compose pull web && docker-compose stop && docker-compose rm -f && docker-compose up -d --build"
only:
- tags
environment:
name: staging
url: https://xxx.com

说明

首先使用EsLint进行代码格式检查, 每次合并到主干分支, 进行构建检查, 每次添加Tags, 构建Docker镜像,并进行部署

配置

在项目根目录,新建.styleci.yml 配置文件,并编写配置内容:

1
2
preset: psr2

查看

打开https://styleci.io/,使用Gitlab账号登录,找到对应的项目,点击右侧的 ENABLE STYLECI 启用按钮,即可使用,

每次提交代码,都会看到检测结果

提示

如果没有找到自己的项目,打开 https://styleci.io/account#repos 点击 Sync With GitHub 同步,就会看到

概述

公司的GitLab中,有一个存放所有技术文档的Wiki仓库,按照目录分门别类,包括API文档,编码规范,技术专题文档等,通过与Gollum进行持续部署.

然而在GitLab中,每个项目都有自己的Wiki库, 所以在将项目文档合并更新到总Wiki仓库时,同步更新比较麻烦,通过充分使用GitLab的持续集成功能, 将项目Wiki与Wiki仓库集成, 从而实现了Wiki的自动部署,

同步时,自动同步的提交信息和提交人信息

步骤

配置SSH

  • GitLab中在使用SSH的时候, 会生成公钥和私钥对

  • 将公钥添加到gitlab上, 以便于该用于可以拉取代码

  • CI/CD Piplines中设置 Secret Variables, 这里名为 SSH_PRIVATE_KEY

SSH_PRIVATE_KEY 值为私钥.

编写 .gitlab-ci.yml 文件, 注入私钥, 通过ssh执行远程命令

创建一个分支, 如docs, 在该分支中添加 gitlab-ci.yml文件, 实现wiki自动提交, 内容形如以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

image: zacksleo/docker-composer:develop

before_script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" > deploy.key
- chmod 0600 deploy.key
- ssh-add deploy.key
- rm -f deploy.key
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

build-docs:
stage: deploy
variables:
GIT_STRATEGY: none
dependencies: []
script:
# 定义变量: 项目Wiki的Git地址,项目(目录)别名
- export WIKI_REPO=git@domain.com:project.wiki.git && export PROJECT_NAME=$CI_PROJECT_NAME
# 创建临时目录, 用于存放和合并git文档
- mkdir ~/tmp && cd ~/tmp
# 克隆项目wiki
- git --git-dir=~/tmp/$PROJECT_NAME.wiki.git clone --depth=1 $WIKI_REPO $PROJECT_NAME
# 删除.git 只保留纯文档, 获取最近的提交日志,用户邮箱和名称
- cd $PROJECT_NAME && export GIT_LOG=`git log -1 --pretty=%B` && export GIT_EMAIL=`git log -1 --pretty=%ae` && export GIT_USERNAME=`git log -1 --pretty=%an` && rm -rf .git && cd ..
# 注册Git账号
- git config --global user.email $GIT_EMAIL && git config --global user.name $GIT_USERNAME
# 克隆联络Wiki
- git clone git@domain.com:orgs/wiki.git
# 删除旧wiki, 增加新wiki
- rm -rf wiki/api/$PROJECT_NAME && mv -f $PROJECT_NAME wiki/api
# 增加提交日志并提交
- cd wiki && git add . && git commit -m "$PROJECT_NAME:$GIT_LOG" && git push origin master
# 删除临时目录
- rm -rf ~/tmp
only:
- docs

其中, 将WIKI_REPO后面的git@domain.com:project.wiki.git替换为项目wiki的git地址,
$CI_PROJECT_NAME替换为项目英文别名(如不改则使用当前GitLab的项目名), 用于在文档中心的api下面创建相关目录。
其他地方不需要修改。

注意: 项目wiki的git地址与项目的git地址不相同, 请在Wiki右侧中的Clone repository 找到

创建 Triggers Token

打开项目的 CI/CD Pipelines 选项, 找到 Triggers, 点击添加一个Token, 并从下方的 Use webhook 段落找到触发URL, 如

https://domain.com/api/v4/projects/74/ref/REF_NAME/trigger/pipeline?token=TOKEN

将TOKEN替换为上述Triggers中获取的Token, 将 REF_NAME 替换分分支名称 docs, 得到最终URL

配置 Webhooks

打开项目的 integrations 选项, 在URL中, 填写上一步中拿到的URL

相关文档

  • [[GitLab-CI使用Docker进行持续部署]]
  • [[使用Git和Gollum搭建Wiki系统]]

背景

在GitLab-CI中,使用artifacts可以确保所需要传递的文件可靠性,但由于生成的artifacts存在的GitLab上,每次需要远程下载,因此速度相对较慢。
所以,在一些对依赖的准确性要求不高的地方,可以考虑使用cache

cache 简介

cache 顾名思义为缓存,不同的任务之前,缓存可以进行共享。根据配置中的声明,在需要缓存时,GitLab-CI会自动下载缓存,以供当前任务使用。

cache一旦命中,意味着这部分文件不需要重新生成(编译,下载或构建),这样一来,便省去了不少功夫,从而加速了构建过程。

使用

生成cache

1
2
3
4
5
6
7
8
9
10
11
  
build-package:
stage: prepare
script:
- composer install --prefer-dist --optimize-autoloader -n --no-interaction -v --no-suggest
- composer dump-autoload --optimize
cache:
key: "$CI_COMMIT_REF_NAME"
paths:
- vendor

如上,在build-package任务中,声明了cache,其目录为vendor, 当script执行完之后,vendor目录会生成,该任务最后,cache会自动生成(push)

使用cache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

phpcs:
stage: testing
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- vendor
script:
- if [ ! -d "vendor" ]; then
- composer install --prefer-dist --optimize-autoloader -n --no-interaction -v --no-suggest && composer dump-autoload --optimize
- fi
- php vendor/bin/phpcs --config-set ignore_warnings_on_exit 1
- php vendor/bin/phpcs --standard=PSR2 -w --colors ./
except:
- docs

如上,该过程定义了所要使用的cache, 由于cache并不保证每次都命中(即拿到的cache可能为空),周时在script处进行判断,如果cache为空时,重新生成所需文件

对比

以doctor-online为例子,在未使用cache之前 ,使用的是artifacts, 每次构建时间在7分钟左右,

使用cache后,构建时间缩短到了1分钟

参考文档

0%