Android系统制作自定义签名

1、简介
应客户要求为了是特殊定制的系统更具安全,系统ROM需要使用自己定义的签名,还有一些特殊的场景也会更改系统的签名比如在过cts认证测试的时候也会修改平台签名才能测试通过关于签名的问题。这是因为平台默认的是test签名.网上大多说签名的都是app签名而非平台签名。test签名这种类型的key只适用于开发阶段,而且这种秘钥是公开的,谁都可以使用。当发布一款android产品,就需要另外给整个系统签个名,防止被别人盗用。这种系统就是release版本的Android系统。这里就简单记录下方法。

2、制作自己的平台release签名
要对Android系统进行签名,需要生成四种类型的key文件。

a) releasekey
b) media
c) shared
d) platform
我们就拿platform 为例简单介绍下生成过程。
1)进入/Android源码根目录/development/tools目录。

%title插图%num
2)使用make_key工具生成签名文件

development/tools$ sh make_key platform
‘/C=CN/ST=ShanXi/L=Xi`an/O=Company/OU=Department/CN=banfeipeng/emailAddress=2333869@qq.com’

%title插图%num
Enter password for ‘shared’ (blank for none; password will be visible): mypassword <——- 设置你的密码
creating shared.pk8 with no password
Generating RSA private key, 2048 bit long modulus
……………………………………..+++
………………+++
e is 65537 (0x10001)

3)make_key的参数介绍

这里要顺便介绍下make_key的参数。*个参数是要生成key的名字,第二个参数是关于你公司的信息。

key的名字很好理解,就是前面提到的4中类型的key,公司信息的参数比较多,它们的含义如下:

C —> Country Name (2 letter code)

ST —> State or Province Name (full name)

L —> Locality Name (eg, city)

O —> Organization Name (eg, company)

OU —> Organizational Unit Name (eg, section)

CN —> Common Name (eg, your name or your server’s hostname)

emailAddress —> Contact email address

4)生成后的结果如下:

%title插图%num
5)pk8是生成的私钥,而*.x509.pem是公钥,生成时两者是成对出现的.

 

3、修改android平台签名为刚才修改的签名文件

1.修改build/core/config.mk将:

ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
else
DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
endif
修改为:

ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
else
DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/XXXreleasekey
endif

2.将上面生成的签名文件放到 build/target/product/security/XXX/目录

%title插图%num

3.修改external/sepolicy/keys.conf

%title插图%num

 

 

戴尔 PowerEdge 2900 服务器上的志强 E5405 CPU 有没有办法调整一下频率

请教各位大侠,这个 E5405 默认频率是 2G,结果肯定是外频的晶振频率偏低,造成了这个 CPU 的实际运行频率只有 1995.020MHz,但是某个程序要求必须 2G 以上的运行频率,检查到低于 2000M 就被 Pass 了,所以想请教一下各位老大有没有这个服务器 CPU 的超频方法。

BIOS 里应该是没有类似的普通 PC 的调整外频的超频设置,我又不可能硬改(某些贴吧里有修改某某电阻的阻值来提高*终作用在 CPU 上的外频),有没有软的方法,哪怕运行一下欺骗一下这个程序的检测也行。

CPU 有两颗,一共 8 核 8 线程。

方案:
1、修改 BIOS 设置;
2、服务器装的是 ESXi,有没有软件方式修改;
3、虚拟机跑的是 CentOS7,有没有类似软件修改的方法;
4、……

不知道还有什么思路,哪怕就提高 5M 到达 2000MHz 就好了,谢谢。

sun1991 1
sun1991 2019-02-15 12:21:40 +08:00
放虚拟机里跑?
ShunYea 2
ShunYea 2019-02-15 12:40:03 +08:00 via Android
@sun1991 这个服务器运行了 ESXi,里面的虚拟机是 centos7,就是说能不能从某个层面上把频率超上去 5m
dazhangpan 3
dazhangpan 2019-02-15 12:41:07 +08:00 via Android
开 turbo?
trepwq 4
trepwq 2019-02-15 12:46:37 +08:00 via iPhone
感觉改改 esxi 虚拟机配置应该可以
ShunYea 5
ShunYea 2019-02-15 14:34:49 +08:00
@dazhangpan
请教怎么个操作法?这个 CPU 没有睿频。
ShunYea 6
ShunYea 2019-02-15 14:35:16 +08:00
@trepwq
好像有点高深,找不到类似的教程唉。
ccav 7
ccav 2019-02-15 15:31:18 +08:00 via iPhone
花几十块换 cpu 5400 系列现在 钥匙扣价。
ShunYea 8
ShunYea 2019-02-15 18:05:47 +08:00
@ccav 主要是服务器拆机没有普通 PC 方便啊,好多的卡扣,太麻烦了。
chinvo 9
chinvo 2019-02-15 18:08:36 +08:00 via iPhone
@ShunYea #8 我怎么感觉服务器更好拆呢
sdijeenx 10
sdijeenx 2019-02-15 18:10:50 +08:00
自己买 CPU 偷偷换成 E5420,等换人维护的时候再偷偷把原 CPU 装回去~

ShunYea 11
ShunYea 2019-02-15 18:12:04 +08:00
@chinvo
@sdijeenx
好吧,两位老铁的建议,我去淘 2 个 CPU 吧。
chinvo 12
chinvo 2019-02-15 18:12:30 +08:00 via iPhone
另外很好奇,什么样的应用才会这么严格地检查 CPU 主频,一般不是写在用户手册上么
ShunYea 13
ShunYea 2019-02-15 21:41:20 +08:00 via Android
@chinvo 做了个服务出租的功能,但是对方软件相当于对性能有要求,然后对方的脚本就是这样判断的,低于 2000m 就 pass,我也觉得可以有个范围,这样界定太不合理。
julyclyde 14
julyclyde 2019-02-17 21:30:53 +08:00
既然晶振低,那程序咋知道自己运行在 1995 的?
QQ2171775959 15
QQ2171775959 2019-02-20 16:09:23 +08:00
超一下频吧。
ShunYea 16
ShunYea 2019-02-21 17:14:47 +08:00 via Android
@julyclyde 程序自己检测 CPU 不是难事吧,检测低于 2000m 就不通过,这个逻辑很好理解嘛
ShunYea 17
ShunYea 2019-02-21 17:15:16 +08:00 via Android
@QQ2171775959 现在就是想咨询超频的方法

做运维,送你7个常用的服务器资源监控工具

摘要:服务器监控工具功能相当强大,无论何时何地,我们都可以了解到服务器的功能以及性能。服务器监控工具的使用,可以让我们清楚的知道用户可以打开我们的网站,且确保网速不慢。这里为你列出了几个常用的服务器监控工具,为你省去寻找方案的麻烦。
以这台鲲鹏服务器为例,先查看自己操作系统的发行版本

%title插图%num

(1)nmon:支持收集一段时间内,整机的CPU、磁盘、网络、内存等各项资源的使用情况。

%title插图%num

(2)perf:Linux kernel自带的系统性能优化工具,获取指定进程内的调用情况、各线程调用的CPU资源消耗情况,并支持生成火焰图。

%title插图%num

火焰图的生成过程是:

先trace系统,获取系统的profiling数据
用脚本来绘制
#脚本获取
git clone https://github.com/brendangregg/FlameGraph
(3)top:监控进程和整机的CPU、内存资源消耗情况,并支持查看每个CPU核的使用情况。

1.负载:时间,登陆用户数,系统平均负载;

2.cpu:用户态,核心态,NICE,空闲,等待IO,中断等;

3.进程:运行,睡眠,停止,僵尸;

4.内存:总量,已用,空闲(系统角度),缓冲,缓存;

5.交换分区:总量,已用,空闲

任务区域默认显示:进程ID,有效用户,进程优先级,NICE值,进程使用的虚拟内存,物理内存和共享内存,进程状态,CPU占用率,内存占用率,累计CPU时间,进程命令行信息。%title插图%num

(4)iostat:监控每块磁盘的读写次数、数据量大小、使用率。

iostat属于sysstat软件包,可以直接安装。

 yum -y install sysstat
%title插图%num

(5)sar:(System Activity Reporter系统活动情况报告)目前LINUX上*为全面的系统性能分析工具之一,监控每张网卡的网络IO读写次数和数据量大小。

先安装deltarpm再安装sar工具(sar也属于sysstat软件包,可以直接安装。)

yum install deltarpm
yum install sysstat

(6)dstat:监控系统整体的性能信息,包括CPU、磁盘、网络、分页等。输出是彩色的,可读性较强

安装dstat

yum install dstat-0.7.2-12.el7 -y

%title插图%num

(7)htop:htop 是Linux系统中的一个互动的进程查看器,可以让用户交互式操作,支持颜色主题,可横向或纵向滚动浏览进程列表,并支持鼠标操作。

安装htop

yum install -y htop

%title插图%num

htop优点:

▪ 在启动上,比top更快。

▪ 可以横向或者纵向滚动浏览进程列表,以便看到所有的进程和完整的命令行。

▪ 杀进程时不需要输入进程号。

▪ htop支持鼠标操作。

什么是shell和shell编程

1.什么是shell?

shell是你(用户)和Linux(或者更准确的说,是你和Linux内核)之间的接口程序。你在提示符下输入的每个命令都由shell先解释然后传给Linux内核。 说到底,Shell是用户与内核进行交互操作的一种接口,目前*流行的Shell称为bash Shell

Shell是解释执行的脚本语言,所谓脚本语言就是不用编译就可以直接执行的语言。在Shell中可以调用Linux系统命令。

shell的*强大的重要特性是它自身就是一个解释型的程序设计语言,shell 程序设计语言支持在高级语言里所能见到的*大多数程序控制结构,比如循环,函数,变量和数组。shell 编程语言很易学,并且一旦掌握后它将成为你的得力工具。任何在提示符下能键入的命令都能放到一个可执行的shell程序里,这意味着用shell语言能简单地重复执行某一任务。

场景:只知道写shell脚本,却不知道什么是shell?那shell是什么呢?找到了之前在腾讯课堂上看的视频,这是课件笔记

你学Linux的话,不懂shell等同于不懂linux
shell是操作系统的*外层,shell可以合并编程语言以控制进程和文件,以及启动和控制其他程序。
简单来说:shell就是一个用户跟操作系统之间交互的命令解释器

感觉像是java和虚拟机的关系一样

在一些复杂的Linux维护工作中,大量重复的输入和交互操作不但费时费力,而且容易出错.
编写脚本的好处:批量的处理,自动化的完成维护,减轻管理员的负担.

不说不知道,一说吓一跳呀,在工作中经常写一些脚本,就是为了方便。

shell独立于内核,它是链接内核和应用程序的桥梁。内核是linux系统的心脏,从开机自检就驻扎在计算机内存中,直到计算机关闭为止。用户的应用程序存储在计算机硬盘上,仅当需要时才被调入内存。shell是一种应用程序,当用户登陆linux系统时,shell就会被调用到内存执行。

不登录怎么执行呢,好像听说过有nologin 的一种模式

linux的shell脚本是一种特殊的应用程序,常见的shell解释器有很多种使用不同的shell时期内部指令命令提示方式方面会存在一些区别,可以通过/etc/shells文件查看

就是不同命令之间有不同的显示和操作

/bin/bash 是大多数linux中默认的shell解释器。

还有chsh不过不经常用,我们一般都是写bash,头文件中添加#!/bin/bash的标志

如何编写*个Shell脚本(shell 就是命令的集合)

其实就是命令的集合,唯一的区别使shell脚本我们可以优化,加入一些for循环,if条件语句。

linux不以后缀名区分文件,为了方便记忆这里我就以.sh为结尾

编写一个shell

1 [support@CMS01 wdq]$ vim first.sh#!/bin/bash
2 #!/bin/bash
3 #auto my frist scripts
4 #by authors cd
5 echo “hello world”
6 mkdir /home/support/tmp/wdq/test
7 free -m

注释:
#!/bin/bash 主要是为了声明,我所写的均为bash语言(我是用的是bash解释器)[定义我的脚本是shell脚本].{固定格式}
#! 称为sha-bang符号,是shell脚本的起始符,他告诉linux系统这个文件的执行需要指定一个解释器。

ll查看是都有权限

1 [support@CMS01 wdq]$ ll
2 total 8
3 -rw-rw-r– 1 support support 1388 May 9 19:51 backupLogs.sh
4 -rw-rw-r– 1 support support 96 Jul 2 17:16 first.sh
5 [support@CMS01 wdq]$ chmod u+x first.sh
6 #赋执行权限

在执行标准/bin/bash/+脚本来执行,这样的就不需要加权限了。
执行权限的不同方式

1 *种使用*对路径执行
2 第二种使用相对路径执行,如./的方式
3 第三种使用 sh命令来执行 格式 sh 脚本名 不需要执行权限
4 第四种使用 . (空格)脚本名称的方式执行 不需要执行权限 . a.sh
5 第五种使用 source 脚本名称 不需要执行权限(主要用于生效配置文件)
6 建议使用后三种,在生产环境中不要轻易的给文件可执行权限;

2.linux中有哪些shell?

一个系统可以存在多个shell,可以通过cat /etc/shells命令查看系统中安装的shell,不同的shell可能支持的命令语法是不相同的,但是*常用的shell还是/bin/bash。下面的演示也基于/bin/bash

1  [robot@hadoop103 ~]$ cat /etc/shells
2  /bin/sh
3  /bin/bash
4  /sbin/nologin
5  /usr/bin/sh
6  /usr/bin/bash
7  /usr/sbin/nologin
8  /bin/tcsh
9  /bin/csh

1  sh(全称 Bourne Shell): 是UNIX*初使用的 shell,而且在每种 UNIX 上都可以使用。
2  Bourne Shell 在 shell 编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种 shell。
3  bash shell(全称 Bourne Again Shell): LinuxOS 默认的,它是 Bourne Shell 的扩展。
4  与 Bourne Shell 完全兼容,并且在 Bourne Shell 的基础上增加了很多特性。可以提供命令补全,命令编辑和命令历史等功能。
5  它还包含了很多 C Shell 和 Korn Shell 中的优点,有灵活和强大的编辑接口,同时又很友好的用户界面。

3.演示一个demo

一个简单的shell实例(用shell脚本语言启动tomcat)
#!/bin/sh
cd /usr/local/apache-tomcat-5.5.23/bin/
./catalina.sh start
文件取名为tomcat
说明
这个脚本只有三行,它的*行指明这个脚本程序由那个程序来解释。
第二行只有一个简单的动作进入某个目录,第三行调用catalina.sh脚本启动tomcat。
执行脚本
执行脚本前先赋予tomcat脚本可执行权限,命令如下:chmod +x tomcat ,
否则会出现如下错误:-bash: ./tomcat: Permission denied #当然如果直接用sh tomcat执行,不需要u+x赋予执行权限
假设tomcat脚本所在目录为为/home/amy/
在/home/amy/目录下执行脚本: ./tomcat
在别的目录下执行脚本: /home/amy/tomcat

4.Shell编程模型

%title插图%num

5.Shell基本的执行方式

1  首先要赋予+x权限,赋予脚本执行权限
2  *种:输入脚本的*对路径或相对路径
3    /root/helloWorld.sh
4    ./helloWorld.sh
5  或者,不用赋予+x权限,而用解释器解释执行u+x
6  第二种:bash或sh +脚本
7    sh /root/helloWorld.sh
8    sh helloWorld.sh
9  第三种:在脚本的路径前再加”. ”
10    . /root/helloWorld.sh
11    . ./helloWorld.sh #注意这里两个点。当然加一个点也可以执行,属于*种
12  区别:*种和第二种会新开一个bash,不同bash中的变量无法共享

Python—random,time,PIL库

Python—random,time,PIL库

文章目录
random库
生成随机数字
列表随机挑选元素
time模块
PIL类
random库
random.seed(a=None, version=2)

设置随机种子,若不想让随机函数,有随机性,可以手动设置种子,以后每次随机出来的数字就会一样了

生成随机数字
random.randrange(stop)

random.randrange(start, stop[, step])

在range()中随机挑选一个数字。

从 range(start, stop, step) 返回一个随机选择的元素。 这相当于 choice(range(start, stop, step)) ,但实际上并没有构建一个 range 对象。

random.randint(a, b)

在[a,b]中随机挑选一个整数

列表随机挑选元素
random.choice(seq)

从非空序列 seq 返回一个随机元素。 如果 seq 为空,则引发 IndexError。

random.choices(population, weights=None, *, cum_weights=None, k=1)

从population中选择替换,返回大小为 k 的元素列表。 如果 population 为空,则引发 IndexError。

如果指定了 weight 序列,则根据相对权重进行选择。 或者,如果给出 cum_weights 序列,则根据累积权重(可能使用 itertools.accumulate() 计算)进行选择。 例如,相对权重[10, 5, 30, 5]相当于累积权重[10, 15, 45, 50]。 在内部,相对权重在进行选择之前会转换为累积权重,因此提供累积权重可以节省工作量。

若即未指定weight也未指定cum_weights,则以相等的概率进行选择,如果提供了权重序列,则它必须与population序列的长度相同。

有放回的随机抽样

random.shuffle(x[, random])

将x序列随机打乱位置。

没有返回值,在原序列上进行修改。

对于样本量大的对象,且不想打乱顺序的,可以打乱对象的索引。random.shuffle(range(len(x)))

random.sample(population, k)

返回从总体序列或者集合中选择的唯一元素的k长度的列表。无重复的随机抽样。

返回一个新列表,保持原始总体不变。

例如:sample(range(10000000), k=60)

random.random()

返回[0.0 , 1.0)范围内的一个随机浮点数。

random.uniform(a, b)

返回一个随机浮点数。范围[小,大]

eval(‘1+3’)它会将1+3字符串的引号去掉,然后计算它的值。

time模块
time.time()时间戳。从1970年1月1日00:00:00到现在的秒数

time.asctime()当地时间,返回一个字符串类型

time.localtime()本地时间,返回一个时间对象的字符串

time.ctime()当地时间,一般使用这个函数获取当地时间

time.strftime(‘%Y-%m-%d %H:%M:%S’)将时间转化为指定格式的字符串。

time.strptime(‘2020-05-29 14:27:21′,’%Y-%m-%d %H:%M:%S’)将指定格式的字符串,转化为时间类型的字符串

time.sleep(2)休眠2秒

PIL类
第三方库
%title插图%num

莱文斯顿距离(python版)

莱文斯顿距离(python版)

莱文斯顿距离(python版)
leetcode No.72
leetcode No.72
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的*少操作数 。

你可以对一个单词进行如下三种操作:

插入一个字符
删除一个字符
替换一个字符
示例:

输入:word1 = “intention”, word2 = “execution”
输出:5
解释:
intention -> inention (删除 ‘t’)
inention -> enention (将 ‘i’ 替换为 ‘e’)
enention -> exention (将 ‘n’ 替换为 ‘x’)
exention -> exection (将 ‘n’ 替换为 ‘c’)
exection -> execution (插入 ‘u’)

首先,使用动态规划思想,首先创建一个二维数组subset,长度为len(word2) + 1,宽度为len(word1) + 1,二维数组中的每一个位置用来记录每一步的*小距离。其中*行表示word1为空字符串,并依次从空字符串变成word2(依次插入);*列表示word2为空字符串,并依次从word1变成空字符串(依次删除)。根据上面已知条件对数组进行初始化赋值。

然后,按照以下条件依次对二位数组中的每个位置(row, column)进行赋值:
(1)当word1[row – 1] != word2[column – 1]时,subset[row][column] 的取值等于该位置左方、上方、左上方距离为1的位置的*小值加1,即
subset[row][column] = min(subset[row – 1][column – 1], subset[row – 1][column], subset[row][column – 1]) + 1
(2)当word1[row – 1] == word2[column – 1]时,subset[row][column] 的取值等于该位置左上方的值,可以理解为由于字符相等编辑距离无需加1操作,即当前*小距离等于同时删除word1以及word2的当前字符的*小距离(左上方距离为1处的值)。

下面解释一下二维数组中的移动方向分别表示的意义:

↓ 表示删除word1的当前字符操作(距离+1)
→ 表示插入word2的当前字符操作(距离+1)
↘ 表示将当前word1的字符替换为word2的当前字符(距离+1)
↖ 可以理解为当前word2的字符与当前word1的字符相同时,同时将这两个字符删除(距离维持不变)
举例,word1=kitten,word2=sitting

%title插图%num
word1与word2*小编辑距离即为二维数组*右下方的值:
subset[-1][-1] == 3

代码(python):

def minDistance(word1, word2):
length1 = len(word1) + 1
length2 = len(word2) + 1
subset = [[0] * length2 for i in range(length1)]
for i in range(length2):
subset[0][i] = i
for j in range(length1):
subset[j][0] = j
for row in range(1, length1):
for column in range(1, length2):
if word1[row – 1] != word2[column – 1]:
subset[row][column] = min(subset[row – 1][column – 1],\
subset[row – 1][column], subset[row][column – 1]) + 1
else:
subset[row][column] = subset[row – 1][column – 1]
return subset[-1][-1]

测试:

word1, word2 = “horse”, “ros”
print(minDistance(word1, word2))

输出:

3

一个创业公司的API网关落地实践

HelloFresh是一家食品电商初创公司,用户根据选定的菜谱下单,HelloFresh把菜谱所需要的食材送至用户家中。来自HelloFresh的技术负责人Ítalo Lelis在博客上分享了HelloFresh的API网关落地实践,本文为该博文的译文,并已获得原网站的翻译授权。

HelloFresh的规模一直保持着增长的态势,我们的产品在持续改进,新的想法不断涌现出来,我们拥有完全自动化的供应链。持续的增长给我们带来了惊喜,同时也带来了技术方面的挑战。

在这篇文章里,我将会和大家分享我们的基础设施所经历的一次重大迁移,这次迁移保证了以后的路我们可以走得更快、更灵活,也更安全。

我们*近开发了一个API网关(github.com/hellofresh/janus),所以接下来需要在不停机的情况下对网关后面的主API(单体系统)进行迁移改造。升级之后,我们希望能够开发更多的微服务系统,并且无缝对接到目前我们的基础架构中。

API网关处在基础设施的*外层,它每天需要接收大量的请求,所以我们选择了Go语言来构建网关,因为Golang性能好、简单易用,而且提供了优雅的并发解决方案。我们手头已经有很多现成的工具,它们可以简化我们的迁移工作。

服务发现和客户端负载均衡

我们使用Consul作为服务发现工具,它和HAProxy配合起来使用可以帮我们解决微服务架构的两个主要问题:服务发现(新服务上线时会自动注册)和客户端负载均衡(把请求均衡地分发到各个服务器上)。

自动化

我们的工具箱里*有用的工具或许要数基础设施的自动化。我们使用Ansible在云端管理资源,包括单机、网络、DNS、运行持续集成工具的主机,等等。按照我们的惯例,开发一个新服务时,我们工程师的*件事情就是为这个服务创建Ansible脚本。

日志和监控

从某种程度上说,我们应该监控基础设施里的所有东西。在日志和监控应用方面,我们有一些*佳实践。

  • 办公室里有仪表盘(就是国内公司里的大电视屏,显示系统状态),我们在任何时候都可以查看系统的运行情况。
  • 我们使用ELK技术栈来收集日志,从而可以快速地分析服务的运行情况。
  • 我们使用Statsd和Grafana作为监控工具,这些工具总会给我们带来惊喜。

Grafana的仪表盘为性能度量指标提供了非常完美的视角。

 

理解当前的架构

尽管有了这些工具,我们仍然有一个棘手的问题需要解决:理清当前的架构,然后想清楚如何顺利地进行迁移。我们花了一些时间对遗留系统进行了重构,让它们支持新的网关,同时我们也加入了认证服务。在这个过程中,我们遇到了一些问题。

  • 虽然我们可以对移动应用进行更新,但也要考虑到有些用户可能不愿意升级,所以我们要保持向后兼容,比如DNS,我们要确保旧版本也能正常工作。
  • 我们需要整理出所有公开和私有的API端点,并让它们自动地注册到网关上。
  • 我们需要把认证工作从主API迁移到新的认证服务上。
  • 确保网关和微服务之间通信的安全性。

为了解决这些问题,我们写了一个Go脚本,这个脚本会读取OpenAPI规范(Swagger)文件并为API资源创建规则(比如速率限定、配额、CORS等)代理。

我们在staging环境搭建了整个基础设施,并在上面运行自动化测试,对服务间的通信进行了测试。不得不说,自动化staging测试在整个迁移过程中起到了很大的作用。我们有很多功能测试用例,这些用例保证了主API的功能是完好的。

在确保了staging环境一切正常之后,我们开始考虑如何将它们推到生产环境。

 

*次尝试

可以告诉大家的是,我们的*次尝试简直是灾难性的。尽管我们已经做足了计划,不过仍然不足以把它们推向生产环境。先来看看我们的初始计划。

  • 把*新的API网关部署到staging环境
  • 把主API的变更部署到staging环境
  • 在staging环境运行自动化功能测试
  • 通过网站和移动端进行staging环境的手动测试
  • 把*新的API网关部署到生产环境
  • 把主API的变更部署到生产环境
  • 在生产环境运行自动化功能测试
  • 通过网站和移动端进行生产环境的手动测试
  • 庆祝胜利

在staging环境一切进展得都很顺利,当我们准备进入生产环境时,问题出现了。

  • 认证服务的数据库过载:我们低估了请求的流量,造成数据库拒*连接
  • 错误的CORS配置:部分端点的CORS规则配置错误,造成请求无法获得资源

数据库被冲垮,我们不得不马上回滚。幸运的是,我们的监控系统捕获到了从认证服务获取令牌的问题。

第二次尝试

从*次失败中吸取了教训,我们知道我们还没有为进入生产环境做好准备,于是在回滚之后,立即对问题展开诊断。在再次尝试之前,我们做了一些改进。

  • 准备蓝绿(blue-green)部署过程。我们为生产环境创建了一个副本,包括已经部署好的网关,通过一些简单的配置变更就能让整个集群运行起来,如果需要回滚,也只需做一些简单的配置变更。
  • 从当前的系统收集更多的度量指标,这样可以帮助我们决定该使用多少机器来处理负载。我们利用*次尝试时所使用的数据作为探针,并使用Gatling来运行负载测试,确保我们可以应付预期的流量。
  • 再次进入生产环境之前,我们对认证服务的已知问题进行了修复,包括一个大小写问题、一个JWT签名的性能问题,并添加了更多的日志和监控。

我们花费了一个*拜来完成上述的工作,之后的部署进展得很顺利,中间没有停机。不过尽管部署进展得很顺利,我们仍然发现了一些在自动化测试中没有发现的个别问题,不过这些问题*终得到修复,并没有对系统造成太大影响。

*终结果

*终的架构如下图所示。

 

主API

  • 10多个主API部署在装配了高端CPU的主机上
  • 主从MySQL(3个副本)
  • 认证服务

4个应用服务器

  • 主从PostgreSQL(2个副本)
  • RabbitMQ用于异步地处理用户的更新操作
  • API网关

4个应用服务器

  • 主从MongoDB(4个副本)

其它

  • 使用Ansible批量管理远程服务器
  • 使用Amazon CloudFront作为CDN/WAF
  • 使用Consul和HAProxy作为服务发现和客户端负载均衡工具
  • 使用Stasd和Grafana收集系统度量指标并触发告警
  • 使用ELK技术栈从不同的服务收集日志
  • 使用Concourse CI作为持续集成工具

 

linux shell脚本EOF妙用

在平时的运维工作中,我们经常会碰到这样一个场景:
执行脚本的时候,需要往一个文件里自动输入N行内容。如果是少数的几行内容,还可以用echo追加方式,但如果是很多行,那么单纯用echo追加的方式就显得愚蠢之*了!
这个时候,就可以使用EOF结合cat命令进行行内容的追加了。

下面就对EOF的用法进行梳理:
EOF是END Of File的缩写,表示自定义终止符.既然自定义,那么EOF就不是固定的,可以随意设置别名,在linux按ctrl-d就代表EOF.
EOF一般会配合cat能够多行文本输出.
其用法如下:
<<EOF        //开始
….
EOF            //结束

还可以自定义,比如自定义:
<<BBB        //开始
….
BBB              //结束

通过cat配合重定向能够生成文件并追加操作,在它之前先熟悉几个特殊符号:
< :输入重定向
> :输出重定向
>> :输出重定向,进行追加,不会覆盖之前内容
<< :标准输入来自命令行的一对分隔号的中间内容.

先举一个简单的例子,例1:
# cat << EOF
在出现输入提示符”>”,输入以下内容:
> Hello
> EOF
输入结束后,在终端显示以下内容:
Hello

思考:
我们可以从cat命令的说明中知道,cat的操作对象是文件,但是例1中cat的操作对象不是文件,而是用户输入。

那么我们可以这样理解例1:先在文件file中输入“Hello”,再用cat file输出其中的内容。
也就是说我们可以用一个文件来替代”<< EOF EOF”。
反过来说,如果操作命令中的文件是输入对象,也可以用”<< EOF EOF”来替代的。

为了验证上面的思考,我们试验两个例子:
例2. 假设有如下的磁盘分区脚本:
sfdisk -uM /dev/sda << EOF
,2048,b
,1024,83
,1024,83
EOF
根据之前的思考,将”<< EOF”和”EOF”之间的内容保存到文件part中,然后将脚本修改为:
sfdisk -uM /dev/sda < part
经测试,修改后的方式可以达到同样的分区结果。

例3. 将一个文件的内容输出到另一个文件中:
# cat fileA > fileB
按照之前的思考,将”<< EOF EOF”替代输入对象文件fileA:
# cat << EOF > fileB
经测试,命令执行后提示用户输入内容,输入结束后,用户的输入内容被保存到了fileB中。

综上所述,“<< EOF EOF”的作用是在命令执行过程中用户自定义输入,它类似于起到一个临时文件的作用,只是比使用文件更方便灵活。

下面通过具体实例来感受下EOF用法的妙处:
1)向文件test.sh里输入内容。
[root@slave-server opt]# cat << EOF >test.sh
> 123123123
> 3452354345
> asdfasdfs
> EOF
[root@slave-server opt]# cat test.sh
123123123
3452354345
asdfasdfs

追加内容
[root@slave-server opt]# cat << EOF >>test.sh
> 7777
> 8888
> EOF
[root@slave-server opt]# cat test.sh
123123123
3452354345
asdfasdfs
7777
8888

覆盖
[root@slave-server opt]# cat << EOF >test.sh
> 55555
> EOF
[root@slave-server opt]# cat test.sh
55555

2)自定义EOF,比如自定义为wang
[root@slave-server opt]# cat << wang > haha.txt
> ggggggg
> 4444444
> 6666666
> wang
[root@slave-server opt]# cat haha.txt
ggggggg
4444444
6666666

3)可以编写脚本,向一个文件输入多行内容
[root@slave-server opt]# touch /usr/local/mysql/my.cnf               //文件不提前创建也行,如果不存在,EOF命令中也会自动创建
[root@slave-server opt]# vim test.sh
#!/bin/bash

cat > /usr/local/mysql/my.cnf << EOF                                      //或者cat << EOF > /usr/local/mysql/my.cnf
[client]
port = 3306
socket = /usr/local/mysql/var/mysql.sock

[mysqld]
port = 3306
socket = /usr/local/mysql/var/mysql.sock

basedir = /usr/local/mysql/
datadir = /data/mysql/data
pid-file = /data/mysql/data/mysql.pid
user = mysql
bind-address = 0.0.0.0
server-id = 1
sync_binlog=1
log_bin = mysql-bin

[myisamchk]
key_buffer_size = 8M
sort_buffer_size = 8M
read_buffer = 4M
write_buffer = 4M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
port = 3306
EOF

[root@slave-server opt]# sh test.sh           //执行上面脚本
[root@slave-server opt]# cat /usr/local/mysql/my.cnf    //检查脚本中的EOF是否写入成功
[client]
port = 3306
socket = /usr/local/mysql/var/mysql.sock

[mysqld]
port = 3306
socket = /usr/local/mysql/var/mysql.sock

basedir = /usr/local/mysql/
datadir = /data/mysql/data
pid-file = /data/mysql/data/mysql.pid
user = mysql
bind-address = 0.0.0.0
server-id = 1
sync_binlog=1
log_bin = mysql-bin

[myisamchk]
key_buffer_size = 8M
sort_buffer_size = 8M
read_buffer = 4M
write_buffer = 4M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
port = 3306

———————————————————————————
下面分享一个自动新建分区并挂载的脚本:

%title插图%num

iOS 入门简介

iOS 入门简介
概述
iOS(原名 iPhone OS,自 iOS 4 后改名为 iOS)是苹果公司为移动设备所开发的专有移动操作系统,所支持的设备包括 iPhone、iPod touch 和 iPad。与 Android 不同,iOS 不支持任何非苹果的硬件设备。

iOS 是由苹果公司开发的移动操作系统。苹果公司*早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,*初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。*初苹果公司并没有给随 iPhone 发行的 iOS 一个独立的称谓,直到 2008 年才取名为 iPhone OS,并在 2010 年 6 月改名为 iOS。2012 年发布四英寸设备 iPhone 5,从此开启多屏幕适配的道路。WWDC 2013 中,苹果发布了 iOS 7,彻底更改了用户界面,将原本拟物的风格转变为平面化风格。

2007:*个 iOS 版本,提出为它提供软件支持。iPhone 1 上市。
2008:操作系统系统取名为 iPhone OS,AppStore 出现。iPhone 3G 上市。
2009:iPhone OS 3 发布,增加复制粘贴,Spotlight 搜索和语音控制等,拟物化设计。iPhone 3GS 上市。
2010:iPhone OS 改名为 iOS,增加双击 Home 键跳转应用。iPhone 4 上市。
2011:iOS 5 发布,增加 iCloud,新的 iMessage 和通知中心。iPhone 4s 上市。
2012:iOS 6 发布,增加自己的地图服务。iPhone 5 上市。
2013:iOS 7 发布,扁平化设计,增加 Touch ID 允许通过指纹识别来解锁设备。iPhone 5c/5s 上市。
2014:iOS 8 发布,增加在 Mac 上也可以阅读和编辑 iMessages,或者接听电话。iPhone 6/6 plus 上市。
2015:iOS 9 发布。iPhone 6s/6s plus 上市。
2016:iOS 10 发布,增加家庭 App,通知可直接显示图片和视频。iPhone SE/7/7 plus 上市。
2017:iOS 11 发布,增加对 AR 的支持,提供 ARKit。iPhone X/8/8 plus 上市。
……
系统架构

%title插图%num

iOS 系统分为可分为四级结构,由上至下分别为可触摸层(Cocoa Touch Layer)、媒体层(Media Layer)、核心服务层(Core Services Layer)、核心系统层(Core OS Layer),每个层级提供不同的服务。低层级结构提供基础服务如文件系统、内存管理、I/O 操作等。高层级结构建立在低层级结构之上提供具体服务如 UI 控件、文件访问等。

iOS 8.3 系统框架架构图

%title插图%num

可触摸层(Cocoa Touch Layer)
大部分与用户界面有关,本质上来说它负责用户在 iOS 设备上的触摸交互操作。这一层基本都是基于 Objective-C 的接口。

可触摸层主要提供用户交互相关的服务如界面控件、事件管理、通知中心、地图,包含以下框架:

UIKit(界面相关)
EventKit(日历事件提醒等)
Notification Center(通知中心)
MapKit(地图显示)
Address Book(联系人)
iAd(广告)
Message UI(邮件与 SMS 显示)
PushKit(iOS8 新 push 机制)
媒体层(Media Layer)
通过它我们可以在应用程序中使用各种媒体文件,进行音频与视频的录制,图形的绘制,以及制作基础的动画效果。这一层既有基于 Objective-c 的接口也有基于 C 语言的接口。

媒体层主要提供图像引擎、音频引擎、视频引擎框架:

图像引擎(Core Graphics、Core Image、Core Animation、OpenGL ES)
音频引擎 (Core Audio、 AV Foundation、OpenAL)
视频引擎(AV Foundation、Core Media)
核心服务层(Core Services Layer)
可以通过它来访问 iOS 的一些服务。基本都是基于 C 语言的接口。

核心服务层为程序提供基础的系统服务例如网络访问、浏览器引擎、定位、文件访问、数据库访问等,主要包含以下框架:

CFNetwork(网络访问)
Core Data(数据存储)
Core Location(定位功能)
Core Motion(重力加速度,陀螺仪)
Foundation(基础功能如 NSString)
Webkit(浏览器引擎)
JavaScript(JavaScript 引擎)
核心系统层(Core OS Layer)
它包括内存管理、文件系统、电源管理以及一些其他的操作系统任务。它可以直接和硬件设备进行交互。作为 App 开发者不需要与这一层打交道。基本都是基于 C 语言的接口。核心系统层提供为上层结构提供*基础的服务如操作系统内核服务、本地认证、安全、加速等。

操作系统内核服务(BSD sockets、I/O 访问、内存申请、文件系统、数学计算等)
本地认证(指纹识别验证等)
安全(提供管理证书、公钥、密钥等的接口)
加速 (执行数学、大数字以及 DSP 运算,这些接口 iOS 设备硬件相匹配)

在上面所有的框架中,*重要也*经常使用的就是 UIKit 和 Foundation 框架。

Foundation 框架提供许多基本的对象类和数据类型,使其成为应用程序开发的基础,为所有应用程序提供*基本的系统服务,和界面无关。

UIKit 框架提供的类是基础的UI类库,用于创建基于触摸的用户界面,所有 iOS 应用程序都是基于 UIKit,它提供应用程序的基础架构,用于构建用户界面,绘图、处理和用户交互事件,响应手势等等。UIKit 通过控制器对象管理屏幕上显示的内容,界面的跳转,来组织应用程序。没有 UIKit 框架就没有 iOS 应用程序。

开发准备
开发环境

Mac OS

开发工具

Xcode

开发语言

Objective-C,Swift(推荐)

Swift 官方资料

Swift 中文资料

Swift 中文教程

iOS 简介

iOS是苹果公司研发的一款手机操作系统。

于2007年开始运用于iPhone,iPod Touch和苹果电视。

iOS是OSX运用于苹果电脑操作系统的一款手机操作系统。

iOS之前被称为 iPhone OS,是一个由苹果公司开发的移动操作系统。

iOS的*个版本是在2007年发布的,其中包括iPhone和iPod Touch。

2004年4月发布iPad(*代),并于2012年11月发布了iPad迷你款。

iOS设备发布相当频繁,由以往经验可知,每年都会推出至少一个版本的iPhone和iPad。

现在发布了iPhone6s,之前还推出了iPhone,iPhone3gs,iPhone4,iPhone4s以及iphone5、iPhone5s、iPhone6。

同样的iPad也从iPad一代更新到iPad四代以及一个特别的迷你版iPad。

iOS SDK已经从1.0更新到6.0。*新的iOS SDK6.0,是唯一支持Xcode4.5和其更高版本的版本。

丰富的苹果文档,使我们能找到许多方法和库用于我们的部署目标。在Xcode的当前版本中,我们能够在iOS4.3,5.0和6.0的部署目标之间选择。

iOS的影响能够从以下的特点显现:

Facebook和Twitter上,加速度计,GPS,高端处理器,相机,Safari浏览器,功能强大的API,游戏中心,在应用程序内购买,提醒,宽范围的手势

  • 地图
  • Siri
  • Facebook 和 Twitter
  • Multi-Touch(多点触摸)
  • Accelerometer(加速度传感器)
  • GPS
  • 高性能处理器
  • 相机
  • Safari浏览器
  • 功能强大的API
  • 游戏中心
  • 在应用程序内购买
  • 提醒功能
  • 手势

iPhone和iPad的用户日益增多,这为iPhone和iPad应用商城的研发者创造了赚钱的机遇。

IOS*新的一点是,苹果公司研发了应用商城,这样用户可以购买应用程序来完善他们的iOS设备。

研发者可以在应用商城发布免费和付费的应用软件。

开发应用程序并将其发布到应用商店,开发人员需要注册iOS开发者计划,为其发展更新Xcode每年话费99美元和Mac Mountain Lion 或更高。

 


注册Apple开发者

对拥有Apple设备的用户来说,非常有必要拥有Apple ID,而且成为一个研发者,必须用到Apple ID,获取 Apple ID是免费的,也无需有资费方面的顾虑。

拥有Apple账户有以下好处:

  • 易于了解研发工具;
  • 全球研发者视频会议;
  • 受邀加入iOS研发者团队;

 


注册苹果账号

1、单击 (https://developer.apple.com/programs/register/) 并选择创建Apple ID

iOS_Free_Reg

2、输入个人信息

3、返回邮箱确认,激活账号

4、下载研发工具,Xcode及它所包含的iOS模拟器,iOS SDK和其他研发资源

 


申请APP开发者

1、点击 (https://developer.apple.com/programs/ios/)

iOS_DeveloperProgram_Reg

2、点击注册页面

3、登录账号(已有账号)或注册Apple ID

4、选择个人账号或公司账号,研发者团队使用公司账号,个人账号不能添加其他用户

5、新用户进入个人信息页面,使用信用卡购买加入研发项目

6、选择会员中心,利用研发者资源

memberCenter

7、在此处可以执行以下操作:

  • 创建资源调配的配置文件
  • 管理团队和设备
  • 通过iTunes Connect管理应用到应用程序
  • 获取论坛和技术支持