iOS开发中MVVM的使用

1.简言

本章针对iOS开发中的MVVM的实践和使用做一个简单的介绍。

2.什么是MVVM?

iOS开发中大家常用的且苹果官方推荐的开发模式是MVC,那么为什么还会使用MVVM作为开发?
MVC的开发模式设计的初衷是解耦,然而该模式在iOS的开发中不可避免会产生耦合。iOS开发中使用MVC开发有以下的缺点:

View的显示不能摆脱控制器,不可避免会造成view和控制器的耦合
VC的任务繁重,既要处理逻辑,又要控制View的显示,VC里面的代码会非常的臃肿
在这里引入MVVM可以很好的解决上述问题。

MVVM中把原有MVC中的控制器和View统一称为View
MVVM中把逻辑处理,数据封装等放在ViewModel中,减轻了控制器的任务
3.一定要使用MVVM?
答案是否。写代码的规则是低耦合,高聚合,个人认为只要能达到这个效果,无论使用MVC还是MVVM都可以。
以下是在开发中使用MVVM和MVC的一些建议:

如果不理解MVVM,不要生硬的去模仿。写出的代码事与愿违,不仅没有达到MVVM的效果,反而耦合性很强,阅读性很差
合理的使用MVVM和MVC,首先MVVM得使用是有代价的,数据和View的双向绑定建立需要一定的时间。一个简单的功能使用MVC可能很快就能实现,如果使用MVVM还要先进行绑定操作,不可避免造成了时间的浪费。
MVVM中各个角色的持有关系。View可以持有ViewModel,但是ViewModel不可以持有View;ViewModel可以持有Model,Model不可以持有ViewModel。在开发中应该保持这样一个原则,避免写出的MVVM耦合性*强。
4.MVVM中View和Model的双向绑定

绑定关系的建立可以依赖第三方库,如ReactiveCoca相关的库实现绑定
自己实现View和Model的绑定。ViewModel中可以设置Delegate,block,KVO等,用来完成model到view的绑定;另外View中也可以通过ViewModel把View的改变通知到model
5.总结

后续会提供MVC和MVVM相关的Demo源码,请大家参考学习,指正。

Mac上安装多个版本的Python

简介
利用Mac包管理工具brew安装pyenv,pyenv用来管理所有python版本。如果没有安装brew,先安装一下吧。

安装pyevn
$ brew install pyenv
$ pyenv -v
pyenv 1.2.6

查看所有的python版本(pyenv管理的所有版本)
$ pyenv versions
* system (set by /Users/xxx/.pyenv/version)
* 表示当前正在使用的版本,system表示用的是系统python版本

查看可安装python版本
$ pyenv install –list
Available versions:
2.1.3
2.2.3
2.3.7

选择版本进行安装
$ pyenv install 3.5.5
python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.5.5.tar.xz…
-> https://www.python.org/ftp/python/3.5.5/Python-3.5.5.tar.xz
Installing Python-3.5.5…
python-build: use readline from homebrew
Installed Python-3.5.5 to /Users/xxx/.pyenv/versions/3.5.5

墙内环境,会卡在这里,可以开代理,或者使用国内镜像。
使用国内镜像:

v=3.5.5|wget http://mirrors.sohu.com/python/$v/Python-$v.tar.xz -P ~/.pyenv/cache/;pyenv install $v
查看所有安装的版本
$ pyenv versions
* system (set by /Users/xxx/.pyenv/version)
3.5.5

可以看到多了一个3.5.5版

我在这一步进行安装的时候出现了一个错误如下:

ownloading Python-3.4.1.tgz…-https://yyuu.github.io/pythons/44a3c1ef1c7ca3e4fd25242af80ed72da941203cb4ed1a8c1b724d9078965dd8
Installing Python-3.4.1…

BUILD FAILED (OS X 10.9.5 using python-build 20150124)

Inspect or clean up the working tree at /var/folders/zf/1b6kcyd53hg0crv65j108_7m0000gn/T/python-build.20150127150918.87726
Results logged to /var/folders/zf/1b6kcyd53hg0crv65j108_7m0000gn/T/python-build.20150127150918.87726.log

Last 10 log lines:
File “/private/var/folders/zf/1b6kcyd53hg0crv65j108_7m0000gn/T/python-build.20150127150918.87726/Python-3.4.1/Lib/ensurepip/__main__.py”, line 4, in <module>
ensurepip._main()
File “/private/var/folders/zf/1b6kcyd53hg0crv65j108_7m0000gn/T/python-build.20150127150918.87726/Python-3.4.1/Lib/ensurepip/__init__.py”, line 209, in _main
default_pip=args.default_pip,
File “/private/var/folders/zf/1b6kcyd53hg0crv65j108_7m0000gn/T/python-build.20150127150918.87726/Python-3.4.1/Lib/ensurepip/__init__.py”, line 116, in bootstrap
_run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
File “/private/var/folders/zf/1b6kcyd53hg0crv65j108_7m0000gn/T/python-build.20150127150918.87726/Python-3.4.1/Lib/ensurepip/__init__.py”, line 40, in _run_pip
import pip
zipimport.ZipImportError: can’t decompress data; zlib not available
make: *** [install] Error 1

使用如下命令即可成功

CFLAGS=”-I$(xcrun –show-sdk-path)/usr/include” pyenv install -v 3.4.1

切换版本
$ pyenv global 3.5.5 # 全局切换
$ python -V # 验证一下是否切换成功

此处用也可用local,只对当前目录生效
$ pyenv local 3.5.5 # 当前目录及其目录切换
$ python -V # 验证一下是否切换成功

此处有坑!
用pyenv versions查看,明明已经切换成功,但是用python -V却还是系统版本。原因是pyenv没有加到$PATH环境变量里去,解决办法如下:

export PYENV_ROOT=~/.pyenv
export PATH=$PYENV_ROOT/shims:$PATH

此时,再次查看python -V,已经成功切换到pyenv指定的版本。

可以把上边两句加到~/.bash_profile里去,永久生效。

有时设置了pyenv local版本后,再设置global会发现没有生效,可以尝试:

pyenv local –unset

解除local设置。

要切换回系统版本,用同样命令:

$ pyenv global system

卸载python版本
$ pyenv uninstall 3.5.5

查看pyenv指令列表
$ pyenv commands
–version
commands
completions
exec
global
help
hooks
init
install
local
prefix
realpath.dylib
rehash
root
shell
shims
uninstall
version
version-file
version-file-read
version-file-write
version-name
version-origin
versions
whence
which

Reference
pyenv的安装和使用
pyenv BUILD FAILED解决方法

在iOS设备中跑Python脚本

在iOS设备中运行python脚本?那不就意味着可以在手机上跑爬虫,可以使用各种牛逼哄哄的python库了吗。

这个标题对我很有吸引力,曾经就有见到过在iOS平台上的python编译器(很多iOS上python的IDE,如Python3IDE),可以执行输入的python语和本地的python文件。

当然我想要的不是像这篇文章说的用python编写一整个iOS程序,而只是在iOS应用中嵌入python文件执行非UI的逻辑,也就是说只需要在项目中嵌入一个python的编译环境。

面对市场上这么多的iOS版python编译器,首先可以确定的是,针对iOS端的python编译库是存在的。我关心的问题是,能否支持python项目化的编译,能否导入丰富的三方库。那就动手一试咯

小目标
七牛的iOS平台SDK有这样一个特点,上传文件的时候需要生成token,但是生成token的逻辑在客户端的SDK中不存在,只能通过调用服务端的SDK才能获得。
于是我们的小目标就诞生了:在iOS端上调用七牛python服务端SDK来生成token给客户端的七牛SDK使用。

iOS的Python解释器
针对iOS、MacOS平台,pybee开源了python支持库Python-Apple-support,这个是老版本的库Python-iOS-support.

准备编译环境
我这次使用的是老库中的Python3.4.2-b5版本,下载下来有两个framework,分别是OpenSSL和Python。将这个两个framework拖入项目中,添加必要的lib库如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i677eEv4-1571197613226)(http://ojam5z7vg.bkt.clouddn.com/15359053297417.jpg)]

在项目中创建PythonEnvironment.bundle将Python.framework中的Restources文件夹内容复制进去,在初始化Python环境之前将bundle中的文件复制到指定目录作为Home路径

设置Home路径、初始化
设置上面准备home路径,并初始化编译环境。

const char * frameworkPath = [[NSString stringWithFormat:@”%@/Resources”,[self p_pythonFrameworkPath]] UTF8String];
wchar_t *pythonHome = _Py_char2wchar(frameworkPath, NULL);
Py_SetPythonHome(pythonHome);

Py_Initialize();
PyEval_InitThreads();

//在释放的时候调用
Py_Finalize();

执行Python代码、文件
编译环境设置好之后,使用PyRun_SimpleString(python_code)便可以简单执行Python代码

PyRun_SimpleString(“print(‘hello world’)”);
1
便可以输出hello world

执行Python文件
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@”test” ofType:@”py”];

FILE *mainFile = fopen([scriptPath UTF8String], “r”);

PyRun_SimpleFile(mainFile, (char *)[[scriptPath lastPathComponent] UTF8String]);

上面是执行main bundle中的Python文件方式,这种方式暂时没有找到如何调用文件中的某各类具体方法和传参。

另外一种方式可以做到上面描述的需求,将在下一节中说明

准备七牛Python库
下载好的七牛SDK文件源码解压,在Xcode中创建一个bundle加入项目中,bundle中放七牛SDK的核心文件,如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3gkKeCdO-1571197613227)(http://ojam5z7vg.bkt.clouddn.com/15359397140219.jpg)]

在需要使用七牛SDK之前,将此bundle中的文件拷贝到Python运行环境的home目录下

编写token生成Python文件
查看七牛的文档了解到生成token需要用到auth.py这个文件中的Auth类, 我们需要想办法创建一个Auth实例并传入需要的参数,再将生成的token导出来。

首先自己创建一个iostoken.py文件,Python的文件名和方法名需要小写,类名需要大写。在iostoken.py中创建TokenForiOS类

import json
from qiniu import Auth

class TokenForiOS(object):

def create_token(jsonParams):
print(str(jsonParams))
values = json.loads(jsonParams)
access_key = values.get(‘access_key’)
secret_key = values.get(‘secret_key’)
#要上传的空间
bucket_name = values.get(‘bucket_name’)
#上传到七牛后保存的文件名
file_name = values.get(‘file_name’)
#构建鉴权对象
q = Auth(access_key, secret_key)
#生成上传 Token,可以指定过期时间等
token = q.upload_token(bucket_name, file_name, 3600)
return token

上面是我使用七牛SDK中的Auth生成token的代码,类名为TokenForiOS方法名为create_token,现在需要找到合适的地方调用。

不过在想要使用TokenForiOS类之前,需要将其加入qiniu模块的初始化__init__.py中:

from .iostoken import TokenForiOS
1
接下来就可以愉快地调用了

Python.framework中有一套宏可以导入Python模块,生成实例,传参调用方法,具体使用例子见下代码块

PyObject *pModule = PyImport_ImportModule([@”qiniu.iostoken” UTF8String]);//导入模块

PyObject *pyClass = PyObject_GetAttrString(pModule, [@”TokenForiOS” UTF8String]);//获取类

PyObject *pyInstance = PyInstanceMethod_New(pyClass); //创建实例

NSMutableDictionary *params = [NSMutableDictionary new];
[params setObject:@”123″ forKey:@”access_key”];
[params setObject:@”456″ forKey:@”secret_key”];
[params setObject:@”jake” forKey:@”bucket_name”];
[params setObject:@”pic” forKey:@”file_name”];

NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&error];
NSString *paramterJsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

PyObject *result = NULL;
result = PyObject_CallMethod(pyInstance, [@”create_token” UTF8String], “(s)”, [paramterJsonString UTF8String] );

char * resultCString = NULL;
PyArg_Parse(result, “s”, &resultCString); //将python类型的返回值转换为c

NSLog(@”%s”, resultCString);

至此,我的小目标就完成啦。后面还有很多事情可以做,比如跑个爬虫试试,毕竟还没有尝试过网络请求。当然也还有很多坑要踩。

总结
使用过程中有下面几点体会

Python-Apple-support库的缺少文档 其实就是Python的API库
设置Home目录导入模块的过程中踩了很多坑
编译器对Python语法提示并不支持,难以排查写错的地方
framework的体积是在过大,对项目总体积影响大
PS:在查询过程中发现了PyObjc这个项目,能够使用python通过bridge调用OC的方法从而使用Cocoa框架,实现使用python编写Cocoa GUI应用。

PyObjC is a bridge between Python and Objective-C. It allows Python scripts to use and extend existing Objective-C class libraries; most importantly the Cocoa libraries by Apple.

This document describes how to use Objective-C class libraries from Python scripts and how to interpret the documentation of those libraries from the point of view of a Python programmer.

SAP 云平台的一些有用链接 – 保证持续更新

Console Client(only valid for Neo)

  1. help

SAP Cloud Platform console client for the Neo environment enables development, deployment and configuration of an application outside the Eclipse IDE as well as continuous integration and automation tasks. The tool is part of the SAP Cloud Platform SDK for Neo environment. You can find it in the tools folder of your SDK location.

就是指这个文件夹下的这些工具:

Supported Java API

  1. help – still for Neo

When you develop applications that run on SAP Cloud Platform, you can rely on certain Java EE standard APIs. These APIs are provided with the runtime of the platform. They are based on standards and are backward compatible as defined in the Java EE specifications.

Cloud Foundry is an engaging open-source platform-as-a-service creating a buzz in the tech world

要在 SCP 上展示 Fiori 应用程序,需要启用 Portal 服务,是指 Cloud 版本的 Fiori Launchpad的界面,用于在云端一站式显示各种 Fiori 或者 SAP UI5 类型的 APP。这和以前推出的 SAP Enterprise Portal 完全不是同一个事物。

SAP HANA Enterprise Cloud: It’s a private managed cloud solution, so in some ways, it’s similar to hosting.

常用链接

Linux 无法本地登录解决方法 报错/lib/security/pam_limits.so

前一段时间,因工作需要在物理机上装了一个Centos6.5,但是,用了一段时间,发现再登录时,无论如何也登不进去了,并且也不提示用户名或者密码错误。我一度以为是在profile以及.bashrc或者.bash_profile里设置了logout命令,于是乎进入单用户模式,各种查看,也没有发现logout的命令。于是,盯着屏幕瞅了一会儿,发现输入正确的用户名和密码以后,会闪一下,但是,特别快,不多瞅几次,无法识别。经过一番细瞅,发现是:Module is unkown,太好了,找解决问题的方法,有提示信息就解决了一半了。

于是,找度娘:

热心网友提供的解决问题的方法是这样的:

1、进入单用户模式

2、查看/var/log/secure文件,日志如下:

Mar 14 11:05:06 testOpenfire login: PAM unable to dlopen(/lib/security/pam_limits.so): /lib/security/pam_limits.so: cannot open shared object file: No such file or directory
Mar 14 11:05:06 testOpenfire login: PAM adding faulty module: /lib/security/pam_limits.so
Mar 14 11:05:10 testOpenfire login: pam_limits(login:session): unknown limit type ‘herd’
Mar 14 11:05:10 testOpenfire login: pam_unix(login:session): session opened for user root by LOGIN(uid=0)
Mar 14 11:05:10 testOpenfire login: Module is unknown
Mar 14 11:05:21 testOpenfire login: PAM unable to dlopen(/lib/security/pam_limits.so): /lib/security/pam_limits.so: cannot open shared object file: No such file or directory

意思是PAM unable to dlopen /lib/security/pam_limits.so这个文件,于是乎去/lib/security/下查看下有没有pam_limits.so这个文件,果然没有。

3、在/etc/pam.d/login里,里面的配置信息如下:

auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth       include      system-auth
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_console.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      system-auth
-session   optional     pam_ck_connector.so
session required /lib/security/pam_limits.so
~
~

经网友指点,将*后一行注释掉或者是改为(搜了下,64位系统在lib64目录下):/lib64/security/pam_limits.so,保存后,重启系统。

4、用原来的用户名和密码登录,完美登录!!

据说,用SSH登录是没有问题的,但是,我的机器IP已经变了,只能登录本机,所以,必须要解决这个问题。但是,我之前用的时候,感觉没有动过这块儿,不知道为啥突然就不能用了。好在问题解决了。真是完美!!

云计算的那些事

云计算的核心思想,是将大量用网络连接的计算资源统一管理和调度,构成一个计算资源池向用户按需服务。

狭义云计算指 IT 基础设施的交付和使用模式,指通过网络以按需、易扩展的方式获得所需资源;广义云计算指服务的交付和使用模式,指通过网络以按需、易扩展的方式获得所需服务。

云计算的特点:

(1)计算资源集成提高设备计算能力。

(2)分布式数据中心保证系统容灾能力。

(3)软硬件相互隔离减少设备依赖性。

(4)平台模块化设计体现高可扩展性。

(5)虚拟资源池为用户提供弹性服务。

(6)按需付费降低使用成本。

3、云计算的类型
软件即服务 软件即服务(Software-as-a-Service, SaaS)是基于互联网提供软件服务的软件应用模式。

平台即服务

平台即服务(Platform-as-a-Service, PaaS)是把服务器平台或者开发环境作为一种服务提供的商业模式,如将软件研发的平台作为一种服务,以 SaaS 的模式提交给用户。

基础设施即服务

基础设施即服务(Infrastructure as a Service, IaaS)是指消费者通过 Internet 可以从完善的计算机基础设施获得服务。

4、应用
云安全

“云安全”通过网状的大量客户端对网络中软件行为的异常监测,获取互联网中木马、恶意程序的*新信息,推送到 Server 端进行自动分析和处理,再把病毒和木马的解决方案分发到每一个客户端。

云存储 应用云存储是在云计算概念上延伸和发展出来的一个新的概念,是指通过集群应用、网格技术或分布式文件系统等功能,将网络中大量各种不同类型的存储设备通过应用软件集合起来协同工作,共同对外提供数据存储和业务访问功能的一个系统。

云存储

当云计算系统运算和处理的核心是大量数据的存储和管理时,云计算系统中就需要配置大量的存储设备,那么云计算系统就转变成为一个云存储系统,所以云存储是一个以数据存储和管理为核心的云计算系统。

云呼叫 应用云呼叫中心是基于云计算技术而搭建的呼叫中心系统,企业无须购买任何软、硬件系统,只需具备人员、场地等基本条件,就可以快速拥有属于自己的呼叫中心,软硬件平台、通信资源、日常维护与服务由服务器商提供。

云会议

应用云会议是基于云计算技术的一种高效、便捷、低成本的会议形式。它是视频会议与云计算的完美结合,带来了*便捷的远程会议体验。

打不开HTTPS网页的解决方案 解决打不开HTTPS 打不开安全网页 无法打开HTTPS 修复打开HTTPS

现象:
当您尝试访问Https打头的网页时,出现错误。

原因:

计算机中的一些设置阻碍了浏览器打开Https网页。

解决方案:

请您尝试打开:
[Internet选项],在“高级”选项卡中的列表中选择上[使用SSL2.0]和[使用SSL3.0]。

然后打开[开始]-[运行],输入“services.msc”,将列表中“HTTPFilter”服务设置为“启用”,状态为“自动”。

如果安装防火墙的话,请打开防火墙,将里面端口限制中允许TCP443端口。

如果上述设置正确后,还是不行,那看下面的*招了,百发百中哦(我的使用此法已解决)

*步:
单击“开始→运行”,输入“cmd”后回车打开命令提示符窗口,
运行“net start cryptsvc” 命令,接下来使用regsvr32命令依次注册
regsvr32 softpub.dll
regsvr32 wintrust.dll
regsvr32 initpki.dll
regsvr32 dssenh.dll
regsvr32 rsaenh.dll
regsvr32 gpkcsp.dll
regsvr32 sccbase.dll
regsvr32 slbcsp.dll
regsvr32 cryptdlg.dll

其中 regsvr32 initpki.dll 可能不会马上就好 ,请稍微等待一下

如果要在已安装 Windows XP Service Pack 2 (SP2) 的系统内修复 Winsock,在命令提示字符中输入 netsh winsock reset,然后按下 ENTER。执行这个命令后,重新启动计算机即可,没有安装SP2的朋友就没有那么幸运了,修复winsock要复杂些..

善意提醒:如果已经中招,而自己的系统还没打上SP2补丁,*好趁此机会重装系统,升级到SP2,安全系数要高得多。不想装SP2,也不想重装系统的朋友,往下看吧!

不带 Service Pack 2 的 Windows XP 说明
要在未安装 Windows XP SP2 的情况下修复 Winsock,请删除已损坏的注册表项,然后重新安装 TCP/IP 协议。
步骤 1:删除已损坏的注册表项
警告:如果使用注册表编辑器或其他方法错误地修改了注册表,则可能导致严重问题。这些问题可能需要重新安装操作系统才能解决。Microsoft 不能保证您可以解决这些问题。修改注册表需要您自担风险。

有关如何备份注册表的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
322756 (http://support.microsoft.com/kb/322756/) 如何在 Windows XP 和 Windows Server 2003 中备份、编辑和还原注册表
1.      单击“开始”,然后单击“运行”。
2.      在“打开”框中,键入 regedit,然后单击“确定”。
3.      在注册表编辑器中,找到下列项,右键单击各项,然后单击“删除”:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock2
4.      在系统提示您确认删除时,单击“是”。
注意:删除 Winsock 项后,请重新启动计算机。这样做可以让 Windows XP 操作系统为这两个项创建新的 shell 条目。如果在删除 Winsock 项后没有重新启动计算机,则下一步无法正常进行。
步骤 2:安装 TCP/IP
1.      右键单击网络连接,然后单击“属性”。
2.      单击“安装”。
3.      单击“协议”,然后单击“添加”。
4.      单击“从磁盘安装”。
5.      键入 C:\Windows\inf,然后单击“确定”。
6.      在可用协议列表中,单击“Internet 协议(TCP/IP)”,然后单击“确定”。
7.      重新启动计算机。

如果你很不辛的话,那你死马当活马,就换不使用IE内核的其它的浏览器,如:oprea, friebox。

九个问题从入门到熟悉HTTPS

女朋友也是软件工程专业,因为快要毕业了,*近一边做毕设一边学习编程。前两天她问我 HTTPS 的问题,本来想直接扔一篇网上的教程给她。后来想了一下,那些文章大多直接介绍概念, 对新手不太友好,于是我干脆亲自给她解释一下,顺便整理了一份问答录。

Q1: 什么是 HTTPS?

BS: HTTPS 是安全的 HTTP

HTTP 协议中的内容都是明文传输,HTTPS 的目的是将这些内容加密,确保信息传输安全。*后一个字母 S 指的是 SSL/TLS 协议,它位于 HTTP 协议与 TCP/IP 协议中间。

Q2: 你说的信息传输安全是什么意思

BS: 信息传输的安全有三个方面:

  1. 客户端和服务器直接的通信只有自己能看懂,即使第三方拿到数据也看不懂这些信息的真实含义。
  2. 第三方虽然看不懂数据,但可以 XJB 改,因此客户端和服务器必须有能力判断数据是否被修改过。
  3. 客户端必须避免中间人攻击,即除了真正的服务器,任何第三方都无法冒充服务器。

很遗憾的是,目前的 HTTP 协议还不满足上述三条要求中的任何一条。

Q3: 这么多要求,一个一个去满足是不是很累?

BS: 不累,第三个要求可以不用管

是的,我没开玩笑,你可以暂时别管第三个要求,因为它实际上隶属于*个需求。我们都知道加密需要密码,密码不是天下掉下来,也得需要双方经过通信才能协商出来。所以一个设计良好的加密机制必然会防止第三者的干扰和伪造。等搞明白了加密的具体原理,我们自然可以检验是否满足:“任何第三者无法冒充服务器”这一要求。

Q4: 那怎么加密信息呢

BS: 使用对称加密技术

对称加密可以理解为对原始数据的可逆变换。比如 Hello 可以变换成 Ifmmp,规则就是每个字母变成它在字母表上的后一个字母,这里的秘钥就是 1,另一方拿到 Ifmmp 就可以还原成原来的信息 Hello 了。

引入对称加密后,HTTPS 的握手流程就会多了两步,用来传递对称加密的秘钥:

  1. 客户端: 你好,我需要发起一个 HTTPS 请求
  2. 服务器: 好的,你的秘钥是 1

提到了对称加密,那么自然还有非对称加密。它的思想很简单,计算两个质数的乘积很容易,但反过来分解成两个质数的乘积就很难,要经过*为复杂的运算。非对称加密有两个秘钥,一个是公钥,一个是私钥。公钥加密的内容只有私钥可以解密,私钥加密的内容只有公钥可以解密。一般我们把服务器自己留着,不对外公布的密钥称为私钥,所有人都可以获取的称为公钥

使用对称加密一般要比非对称加密快得多,对服务器的运算压力也小得多。

Q5: 对称秘钥如何传输

服务器直接返回明文的对称加密密钥是不是不安全。如果有监听者拿到这个密钥,不就知道客户端和服务器后续的通信内容了么?

BS: 利用非对称加密

是这样,所以不能明文传递对称秘钥,而且也不能用一个新的对称加密算法来加密原来的对称秘钥,否则新的对称秘钥同样无法传输,这就是鸡生蛋、蛋生鸡的悖论。

这里我们引入非对称加密的方式,非对称加密的特性决定了服务器用私钥加密的内容并不是真正的加密,因为公钥所有人都有,所以服务器的密文能被所有人解析。但私钥只掌握在服务器手上,这就带来了两个巨大的优势:

  1. 服务器下发的内容不可能被伪造,因为别人都没有私钥,所以无法加密。强行加密的后果是客户端用公钥无法解开。
  2. 任何人用公钥加密的内容都是*对安全的,因为私钥只有服务器有,也就是只有真正的服务器可以看到被加密的原文。

所以传输对称秘钥的问题就迎刃而解了: 秘钥不是由服务器下发,而是由客户端生成并且主动告诉服务器。

所以当引入非对称加密后,HTTPS 的握手流程依然是两步,不过细节略有变化:

  1. 客户端: 你好,我需要发起一个 HTTPS 请求,这是我的 (用公钥加密后的) 秘钥。
  2. 服务器: 好的,我知道你的秘钥了,后续就用它传输。

Q5: 那公钥怎么传输

你好像还是没有解决鸡生蛋,蛋生鸡的问题。你说客户端发送请求时要用公钥加密对称秘钥,那公钥怎么传输呢?

BS: 对公钥加密就行了。。。

每一个使用 HTTPS 的服务器都必须去专门的证书机构注册一个证书,证书中存储了用权威机构私钥加密的公钥。这样客户端用权威机构的公钥解密就可以了。

现在 HTTPS 协议的握手阶段变成了四步:

  1. 客户端: 你好,我要发起一个 HTTPS 请求,请给我公钥
  2. 服务器: 好的,这是我的证书,里面有加密后的公钥
  3. 客户端: 解密成功以后告诉服务器: 这是我的 (用公钥加密后的) 对称秘钥。
  4. 服务器: 好的,我知道你的秘钥了,后续就用它传输。

Q6: 你在逗我么。。。。

那权威机构的公钥又怎么传输?

BS: 存在电脑里

这个公钥不用传输,会直接内置在各大操作系统(或者浏览器)的出厂设置里。之所以不把每个服务器的公钥内置在电脑里,一方面是因为服务器太多,存不过来。另一方面操作系统也不信任你,凭什么你说你这个就是百度/淘宝的证书呢?

所以各个公司要先去权威机构认证,申请证书,然后操作系统只会存储权威机构的公钥。因为权威机构数量有限,所以操作系统厂商相对来说容易管理。如果这个权威机构不够权威,XJB 发证书,就会取消他的资格,比如可怜的沃通。。。。

Q7: 怎么知道证书有没有被篡改?

你说服务器*次会返回证书,也就是加密以后的公钥,那我怎么知道这个证书是可靠的?

BS: 将信息 hash 值随着信息一起传递

我们都知道哈希算法的特点,它可以压缩数据,如果从函数角度来看,不管多复杂的数据(定义域可以非常大)经过哈希算法都会得到一个值,而且这个值处在某个特定(远小于定义域的范围)值域内。相同数据的哈希结果一定相同,不相同数据的哈希结果一般不同,不过也有小概率会重复,这叫哈希冲突。

为了确保原始证书没有被篡改,我们可以在传递证书的同时传递证书的哈希值。由于第三者无法解析数据,只能 XJB 改,那么修改后的数据在解密后,就不可能通过哈希。

比如说公钥就是之前的例子 Hello,我们假设哈希算法是获取字符串的*后一个字符,那么 Hello 的哈希值就是 o,所以加密字符串是 Ifmmpp。虽然公钥已知,每个人都可以解密,解密完也可以篡改,但是因为没有私钥, 所以无法正确的加密。所以它再返回给客户端的数据是无效数据,用公钥解析后会得到乱码。即使攻击者通过多次尝试碰巧能够解析,也无法通过哈希校验。

Q8: 这样可以防止第三方冒充服务器么

BS: 也许可以

首先真正的服务器下发的内容,无法被别人篡改。他们有权威机构的公钥,所以可以解密,但是因为没有私钥,所以解密以后的信息无法加密。没有加密或者错误加密的信息被客户端用公钥解密以后,必然无法通过哈希校验。

但是,如果你一开始请求的就不是真的服务器,而是一个攻击者,此时的他完全有机会进行中间人攻击。我们知道*次握手的时候服务器会下发用于证明自己身份的证书,这个证书会用预设在设备上的公钥来解密。所以要么是经过认证的证书用权威机构的私钥加密,再用权威机构解密,要么是用非权威机构的私钥加密,然后找不到公钥解密。

所以如果不小心安装过非权威机构的根证书,比如黑客提供的恶意证书,这时候设备上就多了一个预设的公钥,那么用恶意私钥加密的证书就能被正常解析出来。所以千万不要随便装根证书,这等于是为那些恶意证书留了一扇门。

当然,凡是都有两面性。我们知道 Charles 可以调试 HTTPS 通信,它的原理就是需要用户安装 Charles 的根证书,然后我们的请求会被代理到 Charles 服务器,它下发的 Charles 证书才能被正确解析。另一方面,Charles 会作为客户端,从真正的服务器哪里拿到正确的 https 证书并用于后续通信。幸好 Charles 不是流氓软件,或者它的私钥一旦泄露,对用户都会造成很大的影响。

我可以举一个例子,证书有多个种类,*贵的叫 EV (Extended Validation),它需要公司营业执照等多个文件才能申请人工审核,好处也很明显,可以在浏览器地址栏左侧准确显示公司名称,比如 Bitbucket 的官网:

EV 证书左侧的名字

这是客户端直连时候的正常现象。但如果你用 Charles 代理,客户端拿到的是 Charles 证书,所以会变成:

代理模式下无法显示

Q9: HTTPS 握手会影响性能么

TCP 有三次握手,再加上 HTTPS 的四次握手,会不会影响性能?

BS: 影响肯定有,但是可以接受

首先,HTTPS 肯定会更慢一点,时间主要花费在两组 SSL 之间的耗时和证书的读取验证上,对称算法的加解密时间几乎可以忽略不计。

而且如果不是首次握手,后续的请求并不需要完整的握手过程。客户端可以把上次的加密情况直接发送给服务器从而快速恢复,具体细节可以参考 图解SSL/TLS协议

除此以外,SSL 握手的时间并不是只能用来传递加密信息,还可以承担起客户端和服务器沟通 HTTP2 兼容情况的任务。因此从 HTTPS 切换到 HTTP2.0 不会有任何性能上的开销,反倒是得益于 HTTP2.0 的多路复用等技术,后续可以节约大量时间。

如果把 HTTPS2.0 当做目标,那么 HTTPS 的性能损耗就更小了,远远比不上它带来的安全性提升。

结语

相信以上九个问题足够帮助新人了解 HTTPS 了,但这只是基本概念,关于 HTTPS 的使用(比如 iOS 上的一些具体问题)还需要不断尝试和研究。

文章*后打一个求职广告,长期有效,女朋友今年毕业,考研 380+,简历戳这里,计算机基础还算扎实,但项目经验偏少,可以实习 6 个月以上。北京地区如果有想要招实习生的公司,欢迎联系我,方向不限,前后端皆可培养,iOS 更好(我自己教)。

人人都能看懂的云计算知识科普

双十一期间,我想很多小伙伴都被阿里云的促销活动刷屏了,大家组队组团,可以得到较为便宜的阿里云服务器。另外,Docker 也红得发紫,与之对应的 DevOps 和 NoOps 持续高温。

但是对于不少企业尤其是传统企业,云仍在天边,对于云仍感觉云里雾里。上云还是不上云,上什么云,这是个问题。我们试着用*通俗的比喻,理清云服务中*基本的那些事儿。

什么是云?
先从一段对话开始。

张三:我们公司的资料不让存放到个人电脑上,一般都存到云上。

李四:别逗了,你们单位就二十几个人,两台服务器,没有虚拟化也没有分布式,能叫云?

张三:那怎么了?几百块钱的西数 NAS 都叫云呢。

张三大概是个普通人,李四是个技术宅,对话也反映出不同人眼中不同的云。那究竟什么是云呢?

历史上已经有不下于一百种的定义,影响力较大的是 NIST(美国国家标准与技术研究院)的定义:

云计算是一种模型,它可以实现随时随地、便捷地、随需应变地从可配置计算资源共享池中获取所需的资源(例如网络、服务器、存储、应用及服务),资源能够快速供应并释放,使管理资源的工作量和与服务提供商的交互减小到*低限度。

显然,对一般的用户来说,这并不好理解,翻译成人话大概是:让计算、存储、网络、数据、算法、应用等软硬件资源像电一样,随时随地、即插即用。这种定义,比较像张三眼中的云,我们称其为广义云计算。

技术宅李四眼中的云是指一整套虚拟化和分布式的技术体系,近几年以去 IOE(即 IBM、Oracle 和 EMC)。为嘛去人家?因为太贵!

不过 IBM、Oracle 和 EMC 的母公司 Dell 都在积*拥抱云计算了)的低成本化为典型特点。

这种,我们称其为狭义云计算。

首先,狭义云计算过度关注底层,而忽略掉了 SaaS (软件即服务)和PaaS(平台即服务);

其次,狭义云计算过度关注具体技术,而忽略掉服务模式、商业模式等,长期看容易低估云计算的社会推动作用。

当然,李四这么说也有一定道理,就目前来说,大部分云的底层架构确实是通过虚拟化和分布式来实现的,毕竟节省成本、容易管理,还支撑了分布式大数据处理。

什么是虚拟化和分布式?
一个村,有很多人家。张三家只有一个女儿,粮食总是吃不完,相当于资源闲置。李四家有五个儿子,粮食总是不够用,相当于资源紧缺。这还不算,王五家时不时来一大堆客人,粮食够不够用谁也说不准,相当于计算波动大。

于是,张三家添了几双筷子几个碗,可以让别人来吃,相当于一台物理机虚拟出更多台虚机。谁家有多少粮食、几张桌子、几双筷子、几个碗,村长记在自己的小本本上,相当于统一调度,形成了资源池。

李四和王五家不够吃的时候,拿小板凳去张三家,相当于分布式。有同学就问了,张三岂不是亏了?别入戏太深,张三只是一台服务器!还有同学说,我为嘛嗅到了共产主义的味道?没错,虚拟化和分布式就是要在计算、存储和网络上实现共产主义!

虚拟化和分布式在共同解决一个问题,就是物理资源重新配置形成为逻辑资源(在 IT 领域称为解耦,也就是你用的东西跟实际物理的东西是两码事,一如李四和王五的午饭其实是在张三家解决的)。其中虚拟化做的是造一个资源池,而分布式做的是用一个资源池。

虚拟化包括计算虚拟化、网络虚拟化和存储虚拟化。

计算虚拟化通常做的是一虚多,即一台物理机虚拟出多台虚拟机,以榨干实际的物理资源,其包括全虚拟化、超虚拟化、硬件辅助虚拟化、半虚拟化和操作系统虚拟化。

类似于计算虚拟化,网络虚拟化同样解决的是网络资源占用率不高、手动配置安全策略过于麻烦的问题,采用的思路同样是把物理的网络资源抽象成一个资源池,然后动态获取,网络虚拟化目前有控制转发分离、控制面开放、虚拟逻辑网络和网络功能虚拟化等不同的思想路线。

存储虚拟化通常做的是多虚一,除了解决弹性、扩展问题外,还解决备份的问题。

公有云、私有云、混合云和社区云是什么东东?
张三、李四、王五住一栋楼,楼下一个大规模的饭店。张三一直在家做饭,这是私有云,厨房是自建机房。李四一直在饭店吃,这是公有云,饭店是云数据中心。王五牛叉,在饭店有个固定包间,包间不对外人开放,这是托管型私有云(有的厂商将其定义为专有云),包间是云数据中心中的托管服务器。

张三家有天来了十多个客人,这是业务突增。家里装不开,要去饭店,这是私有云转公有云。张三妈妈省吃俭用,对张三说,你们去吧,我和你爸在家吃,对张三家来说这是混合云。如果饭店仅对某个特定人群比如学生开放,这就相当于社区云。

当然,举例不十分恰当,毕竟饭还是买的,而云是租的,此点切记。

私有云
私有云是为某个特定用户/机构建立的,只能实现小范围内的资源优化,因此并不完全符合云的本质——社会分工,所以 Openstack 等开源软件带来的私有云繁荣可能只是暂时的,会有越来越多的客户发现廉价的硬件和免费的软件并不是打造私有云的充分条件,精细的管理、7×24 运维所耗去的总成本(TOC)不比公有云低,而且随着公有云厂商运营能力的进步,这种趋势会越来越明显。

托管型私有云在一定程度上实现了社会分工,但是仍无法解决大规模范围内物理资源利用效率的问题。

公有云
公有云是为大众建的,所有入驻用户都称租户,不仅同时有很多租户,而且一个租户离开,其资源可以马上释放给下一个租户,一如饭店里一桌顾客走了马上迎来下一桌顾客。

公有云是*彻底的社会分工,能够在大范围内实现资源优化,因此,不管道路如何曲折,前途总是光明的。当然公有云尤其是底层公有云构建,不是一般人能玩的了的,就像开个三五桌的饭店谁都能行,开个三五万桌的饭店就要看资金和本事了。

很多客户担心公有云的安全问题,敏感行业、大型客户可以考虑,但一般的中小型客户,不管是数据泄露的风险,还是停止服务的风险,公有云都远远小于自己架设机房。

社区云
社区云是介于公有、私有之间的一个形式,每个客户自身都不大,但自身又处于敏感行业,上公有云在政策和管理上都有限制和风险,所以就多家联合做一个云平台。

混合云
混合云*是以上几种的任意混合,这种混合可以是计算的、存储的,也可以两者兼而有之。在公有云尚不完全成熟、而私有云存在运维难、部署实践长、动态扩展难的现阶段,混合云是一种较为理想的平滑过渡方式,短时间内的市场占比将会大幅上升。

并且,不混合是相对的,混合是*对的。在未来,即使不是自家的私有云和公有云做混合,也需要内部的数据与服务与外部的数据与服务进行不断的调用(PaaS 级混合)。并且还有可能,一个大型客户把业务放在不同的公有云上,相当于把鸡蛋放在不同篮子里,不同篮子里的鸡蛋自然需要统一管理,这也算广义的混合。

Iaas、PaaS 和 SaaS 又是什么东东?
IaaS,Infrastructure as a Service,基础设施即服务;
PaaS,Platform as a Service,平台即服务;
SaaS,Software as a Service,软件即服务。
还是不太好理解?没关系,张三李四王五登场。

张三卖小麦,相当于 IaaS;李四卖面粉,相当于 PaaS;王五卖馒头,相当于 SaaS。

张三觉得卖小麦不挣钱且不能打品牌,向下游延伸,也卖起了面粉,相当于 IaaS 企业也逐渐做 PaaS 业务;王五馒头卖得好,一天几万个,面粉需求量非常大,不希望被李四控制,也做起了面粉,相当于 SaaS 企业做 PaaS,所以 IaaS、PaaS 和 SaaS 只是分析师和投资人津津乐道的,从业者并不关注,天下熙熙,皆为利来,啥赚钱搞啥。

张三卖面粉后,与李四就形成了竞争关系,但是李四还经常从自己这里买小麦,相当于又有合作,这种既竞争又合作的关系就叫竟合。

赵六嘴叼,馒头满足不了,非自己包饺子吃,直接从张三那里买小麦或李四那里买面粉,相当于直接利用 PaaS 平台做软件或订制 SaaS,这种嘴叼的一般都是土豪,对应的就是大客户。

有没有发现,越是在城市里,越是发达,种小麦的、买小麦的、买面粉的就越少,买馒头的越多?那就对了,这是社会分工的结果。而云计算同样会向着高度分工的方向进化。

还有同学问,存储到底算是哪一层呢?这就相当于你觉得能灌溉能和面还能直接喝的水是哪一层呢?自然是出现在不同场景时对应不同层:常说的块存储、对象存储一般是指 IaaS 层,而网盘一般是指 SaaS 层。

Iaas
IaaS 提供的一般是通用计算、存储和网络三大基础资源,前面提到的虚拟化、分布式等大多集中在本层,少量「流亡」于 PaaS 层。

一般认为,IaaS 始于亚马逊的 EC2 和 S3 两款产品。近两年,我们说的云计算快速落地,其实主要指 IaaS 的迅速落地,因为原来的公有云确实不稳定,而客户也都在观望。当然,有 IaaS 公司提出自己是「企业级 IaaS」,这就有点噱头了,试问,哪个 IaaS 不是冲着企业级这一目标去的?给开发者玩儿的吗?

Paas
PaaS 定义比较复杂,早年提供的是部署了数据库和开发环境的平台,被称为 XAE(X:企业名首字母;AE:Application engine),XAE 常用于个人建站,商用程度并不高,在中国尤其如此,后来要么转型要么解体了;

后来 PaaS 转为提供某种细分能力,如图像识别、语音识别、推送、通信等,常以 API 或 SDK 进行交付;近两年 Docker 风生水起,成为 PaaS 新秀。

此时回头看原来 PaaS 的各种定义,都不太恰当了,因此比较准确的描述应是:PaaS 提供除计算、存储和网络三大基础资源之外的其他能力(如通用开发能力,细分能力,业务交付能力),但并不对终端用户提供成熟产品。

Saas
SaaS 涵盖的就广了,邮箱是、网盘是、几乎常见的网站都是!但一般所谓的 SaaS 是指:具有一定复杂度的,通常应该在 C/S 架构下主要通过 C 端完成的软件服务,在 B/S 架构下完成了。

当然这个复杂度,在不同的时期有不同的定义,十几年前,邮箱可能都算复杂了,而现在随着 HTML5 技术的成熟,大部分的 Office 操作都可以在浏览器完成。当然,放企业级市场里,SaaS 比较好界定,指以云的方式取代了的原来企业软件系统的服务。

SaaS 始于上世纪九十年代末 Salesforce 等公司,随着移动互联网和 HTML5 的发展而蓬勃发展,强调的是瘦终端。但是,到底多瘦才算瘦,各种应用不再用 APP 而以微信小程序的形式出现算瘦吗?或许,SaaS 的终*进化是纯「裸机」,也就是「桌面云」,当然这只是一种理想,因为不仅关乎软硬件技术,还关乎用户习惯。须知,到现在还有不少用户喜欢把电影放到移动硬盘里,抽屉里一塞,那感觉,踏实!

SaaS *接近于终端用户,是一个巨大的市场。但是,SaaS 是对软件开发水平和服务水平的综合考验,拼得往往不仅是技术本身,还包括对用户的理解、以及设计水平和创意。

如果原来就是卖不出去的软件,没有任何改进包装一下放到云上改为服务也不会有人买单,原来*起码还不用对宕机这种事情负责呢,放云上只是增加了 SaaS 服务商自身的风险。

所以,SaaS *不是单机软件到云上的简单迁移,而是自始至终都应贯穿服务的思想和云的思想,比如多屏同步、多人协同等。也所以,我们虽然看好整体市场,但是并不看好很多 SaaS 领域一堆堆的无价值企业,资本寒冬,*先倒下的往往是他们。

云计算有什么价值?
成本更低、运维成本更低、服务更好、弹性扩展、部署更快、不用采购硬件,云计算的好处总能说出一大堆。

但,这些点往往只反映云计算的一个侧面,有的还不完全正确:比如成本低,客户会发现,如果租用高性能云主机且保证 99.99% 的可用服务时,成本往往并不比自建机房低,在需要的主机(物理机或虚机)量比较大时,尤其明显。

其实,云计算的本质就是社会分工,社会分工所产生的价值云计算都能产生,比如规模化、精细化所产生的成本降低与效率提高等;

而社会分工中产生的问题,云计算也都会面对,比如节省下来的成本到底是买家受益还是卖家受益,再比如垄断。

还是拿蒸馒头举例子,在城市中,大多数家庭不自己蒸馒头而去馒头房买,这是社会分工,节省了社会总体成本,但是买馒头并不比自己蒸更便宜,说明节省了的成本进入了卖家而非买家的腰包。

再比如,当一个城市只剩一家馒头房而大多数家庭又丧失了蒸馒头的能力时,馒头房便有可能提价,这就是垄断。

理解了云计算是一次社会分工的本质,便不会过分夸大其优点,更不会对之回避认为其只不过是一时风潮。从狩猎到农耕、再到工业社会,从一只羊换两把斧子到贝壳、金属货币、纸币、虚拟货币,从生产方式到价值交换方式,你会发现,人们所做的一切都是在朝着社会分工或促进社会分工的方向发展。

所以,对于云,逃也没用,躲也没用,时代总会来临。果断拥抱,理性选择,踏实落地,即是未来。

————————————————

【总结】学习AWS的VPC并通过快速上手实验室动手实操

AWS的服务类型包括
计算、存储内容分发、联网、数据库等10多大类,几十项服务
但是跟网络相关只有2个(VPC和数据中心光纤连接)
AWS的VPC是云计算中网络运维的基石,是SDN能力的体现
VPC是一整套模拟传统网络运维的工具,包括:
子网
DHCP
防火墙(安全组)
路由表(NACL)
DNS
网关
*等众多功能
AWS的快速上手实验室,模式值得学习,包括:
实验概述说明
实验具体操作步骤文档(如按照服务的生命周期维度进行设计:创建、修改、删除1.2.3.4)
实验相关文件附件(如CFN的json)
自动开通的AWS测试账号
针对不同级别级别用户的练习(如基础、高级、专家等)
针对客户实际业务场景的练习(如大数据、移动开发)
2.AWS的服务学习方法
2.1.AWS的云服务列表overview
计算
EC2(云中的虚拟服务器)
EC2 Contrainer Service(运行和管理docker容器)
Elastic Beanstalk(运行和管理web应用程序)
Lambda(事件驱动的计算服务)
存储和内容分发
S3(可扩展的云存储)
CloudFront(全球内容分发网络CDN)
Elastic File System(针对EC2完全托管的文件系统)
Glacier(云中的归档存储-虚拟带库)
Import/Export Snowball(大规模数据传递的硬件)
Sotrage Gateway(混合存储集成)
分析
Elastic MapReduce(Hadoop托管框架)
Kinesis(实时处理流媒体传输)
联网
VPC(隔离的云网络)
Direct Connect(AWS专用网络连接)
数据库
RDS(管理型关系数据库服务)
DynamoDB(可预见,可扩展,全托管的NoSQL数据库)
RedShift(托管的数据仓库)
ElasticCache(内存缓存)
应用程序服务
API Gateway(构建、部署和管理API)
AppStream(低延迟的应用程序流)
CloudSearch(管理型搜索服务)
SQS(消息队列服务)
SWF(协调应用程序组件的工作流服务)
开发人员工具
CodeCommit(在私有Git存储库中存储代码)
CodeDeploy(自动代码部署)
CodePipeline(使用持续交付发布软件)
管理工具
CloudWatch(监控资源和应用程序)
CloudFormation(使用模板创建和管理资源)
CloudTrail(跟踪用户活动和API使用)
Config(跟踪资源库存和变更)
OpsWorks(用Chef自动化操作)
Service Catlog(创建和使用标准化的产品)
Trusted Advisor(优化性能和安全)
安全&身份
IAM(管理用户访问和加密密钥)
物联网
AWS IoT(将设备连接到云)
游戏开发
GameLift(部署和扩展基于会话的多人游戏)
移动服务
Mobile Hub(构建、测试和监控移动应用)
Cognito(用户身份和应用程序数据库同步)??
Device Farm(在云中的真实设备上测试android、ios应用)
SNS(推送通知服务)