麻省理工学院研究人员提议针对幽灵党和熔毁的DAWG

麻省理工学院的安全研究人员声称已经设计出一种硬件解决方案来防止基于推测执行的缓存定时攻击,例如幽灵党和熔解。他们的方法被称为动态分配路径保护(DAWG),将处理器缓存分割成大小不一的分区,使得进程无法窥探其他进程的缓存分区。

自从它们被披露以来,各种软件防御机制已经被提议用于幽灵党和熔毁,但他们通常针对攻击的一个特定变体确切的性能损失。现在,麻省理工学院计算机科学与人工智能实验室(CSAIL)的研究人员宣称,他们已经设计出了一种机制,这种机制仅要求对现有处理器体系结构的硬件做最低限度的修改,以抵御广泛的侧信道攻击,并具有合理的性能开销。

幽灵和崩溃的利用的投机执行,是一种旨在改善处理器的总体性能的机制,它让处理器在等待内存时多执行几个指令,例如,有两个分支的一个条件,丢弃不需要的那些,也就是走不到的那个分支。

在一篇将于几天后在日本福冈市举行的IEEE/ACM微结构国际研讨会(MICRO)上发表的论文中,研究人员Kirianski、Lebedev等人展示了一种针对集关联结构(包括缓存)的安全分区方案,它增加了保护域的概念。根据研究人员的说法,保护域在集合关联结构的分区之间提供了强大的隔离,并且能够检测和防止缓存命中、遗漏和元数据更新。

(图片来自麻省理工学院论文)

动态分配路径保护(DAWG)核心的关键思想是利用传统的集关联内存设计,将控制器和一些直接映射的缓存结合起来,称为路径:

为了实现DAWG,我们将为保护域分配多组路径,限制来自于那些发出的缓存请求到这些路径的缓存命中和行替换。

为了实现这种机制,DAWG需要一些额外的元数据与缓存相关联,相当于一个24位的硬件线程寄存器。寄存器用于存储三个8位活动域选择器。此外,每个缓存需要256位来描述每个活动域允许的方式。研究人员还声称,DAWG几乎不需要为了利用这种机制打麻将修改现有的操作系统。

不得不承认,DAWG还不能抵御各种各样的投机性攻击,它的创建者们正在努力改进它,拓宽它的应用范围。此外,目前还不清楚英特尔或其他CPU制造商是否会采用他们的方法,但Kirianski和Lebedev希望这种情况能够发生。InfoQ将继续报道这方面的内容,以及其他针对基于推测执行的攻击的方法和解决方案。

查看英文原文:MIT Researchers Propose DAWG Defense Against Spectre and Meltdown




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/mit-dawg-spectre-meltdown-fix

短深度量子电路的量子优势已被正式证明

来自IBM T.J.Watson研究中心,加拿大滑铁卢大学(University of Waterloo)和德国慕尼黑工业大学(Technical University of Munich)的研究员们已经在理论上证实了量子计算机能够比传统计算机更快地解决特定问题。他们设计的算法已经达到当前量子计算机处理器的计算能力极限,实验证明可能即将推出。

严格来说,Sergey Bravyi、David Gosset 和 Robert König等三位研究员证明了:

在恒定的时间周期内运行的并行量子算法一定比经典算法更加强大;在解决与二元二次型相关的特定线性代数问题上它们很可能更优。

他们提供的证据基于一种算法,以解决可以在量子常数深度中实现的二次“隐式线性函数”问题。隐式线性函数是一个不完全已知的线性函数,但它“隐藏”在你可以计算的另一个函数中。例如,一个线性函数可以隐藏在一个可以查询的oracle中。挑战是基于应用已知函数的结果来充分表征隐式线性函数。如果这听起来有点类似于将公钥反转以找到其私钥的问题,那么这并不意外,因为这正是它所要解决的问题

在oracle的例子中,这个问题通过经典的Bernstein-Vazirani算法解决,该算法最小化对oracle的查询次数。根据三位研究员的观点,Bernstein-Vazirani算法被应用于oracle的事实限制了它的实际适用性,所以他们建议在二维网格图中“隐藏”一个线性函数。在证明这种做法确实可行之后,他们建立了一个量子常量深度算法来找出隐藏的函数。

研究员们提供的另一半证据表明,与量子电路相反,任何传统电路都需要随输入数量的增加而提高其深度。例如,量子算法可以用一个最大深度为10的量子电路解决该问题,而无论你有多少输入,但反过来看传统呢,对于16个输入的问题,需要一个深度为10的传统电路;对于32个输入的问题,需要一个深度14的电路;对于64个输入的问题,需要一个深度20的电路等等。

证明的第二部分在哲学上是非常有趣的,因为它详述了量子非局域性的概念,而量子非局域性又与量子纠缠有关,量子纠缠与叠加是量子处理器最独特的特性之一。所以,量子优势似乎来自量子物理学最本质的特性。

在理论层面上,这一成就的价值也不可低估。IBM IBM Q副总裁Bob Sutor写道

这个证明是量子算法和经典算法之间无条件分离的首次证明,尽管是在恒定深度计算的特殊情况下。

以前,量子计算机比经典计算机更强大的想法是基于因式分解问题。Shor指出,量子计算机可以在多项式时间内对整数进行因子分解,也就是说比任何已知的经典计算机算法更高效。尽管这是一个有趣的结果,但它并不排除确实可以找到更高效的经典因式分解算法的可能性。因此,除非人们猜想根本不存在高效的因式分解问题解决方案,这等价于证明”P ≠ NP“,否则人们不能真正地说量子优势被证明。

如上所述,Bravyi、Gosset和König的算法依赖于恒定数量的操作(量子电路的深度),这似乎正好适合当前量子计算机处理器的局限。这些基本与量子位的错误率和相干时间有关,它们限制了操作序列的最大持续时间及其总数。因此,使用短深度电路是当前量子电路任何可行应用的关键。Sutor说,由于所提出的算法的这种特性,IBM的研究人员已经开始使用IBM量子计算机来证明量子优势。

如果你有兴趣了解证明的全部细节,请不要错过David Gosset在普里美特理论物理研究所(Perimeter Institute for Theoretical Physics)的演讲以及演示幻灯片

查看英文原文https://www.infoq.com/news/2018/10/quantum-advantage-proved-ibm

感谢冬雨对本文的审校。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/quantum-advantage-proved-ibm

苏宁云自动化部署统一平台Hull

背景

现有解决方案思路

苏宁云是国内比较早使用Kubernetes和Openstack的公司,自动化部署1.0产品使用了比较传统的安装方式,主要的部署工具使用Puppet。现有的自动化部署统一平台使用的是ansible为代表的KubeSpray以及Kolla-Ansible。

苏宁云有一套成熟的部署思路,所以,在设计方案的兼顾了,不破坏社区版本的代码基础上,进行定制化开发,所有定制化的功能都是可插拔的。

统一平台可以让用户的对整体机器资源一目了然;参数统一,用户配置更加方便;同时加强了对部署过程中监控。

走近Kubernetes KubeSpray

KubeSpray整体介绍

KubeSpray是Kubenetes社区孵化的一个方案,现在已经开源,KubeSpray使用了Ansible-playbook进行了编排,依赖于Kubeadm,可以将Kubernetes部署在AWS、GCE、Azure、OpenStack、Vsphere、以及裸机。Kubenetes可以快速部署一个高可用Kubenetes集群。可选的网络查件,KubeSpray支持的网络插件非常多,包括Flannel、Contiv、Weave、Calico等。KubeSpray也支持主流的操作系统发现版。

KubeSpray定制开发非常简单,如果需要增加步骤,只需要修改playbook的入口文件即可,比如cluster.yaml

使用KubeSpray快速搭建Kubernetes平台

是时候动手尝试一下KubeSpray了,他将会改变你对手动部署Kubernetes的繁琐的认识,特别是配置SSL认证。

(关于实验环境,全部是在CentOS7上进行,后续不再说明。)

上一节说了,KubeSpray使用Ansible-Playbook编写,首先安装Ansible,版本大于2.4版本,使用最简单的pip。

$ pip install ansible

Clone 代码

$ git clone https://github.com/kubernetes-incubator/kubespray.git

进入代码目录

从requiremens.txt文件中安装依赖文件

$ pip install -r requiremens.txt

复制资产文件到自定义目录

$ cp -rfp inventory/sample/* inventory/demo_cluster

复制后在demo_cluster结构如下:

在hosts.ini中配置机器资产;

在group_vars/all.yml 配置部署Kubernetes的通用参数

在group_vars/k8s-cluster.yml配置部署Kubernetes的版本,镜像库、端口、网络等。

开始部署Kubernetes

$ ansible-playbook -i inventory/demo_cluster/hosts.ini cluster.yml

以上就是快速部署Kubernetes的步骤,由此看出,KubeSpray上手非常简单。

如果想深入研究KubeSpray,可以参照社区文档,优化all.yml和k8s-cluster.yml中的详细参数。

理解OpenStack Kolla-Ansible

Kolla-Ansible介绍

Kolla-ansible的两大特性,开箱即用以及允许完整定制化。这针对于缺少OpenStack自动化部署的操作者来说,可以快速的部署生产级别的OpenStack环境出来。

使用Kolla-Ansible快速搭建OpenStack平台

下面我们就看看,使用Kolla-Ansible快速搭建一个3个控制节点OpenStack平台。由于部署时分为研发调试方式和生产方式,我们使用生产方式来部署OpenStack。

(关于实验环境,全部是在CentOS7上进行,后续不再说明。)

本次实验使用是一台物理机,配置如下:

  • 32核CPU
  • 64GB内存
  • 50GB root盘 + 850GB数据盘
  • 2块千兆卡 + 2块万兆卡

在正式安装部署之前,假设您对AnsibleDocker有了掌握和了解。

安装依赖

  1. 安装和升级最新版的pip工具

yum install epel-releaseyum install python-pip

pip install -U pip

  1. 安装依赖

yum install python-devel \libffi-devel \gcc \openssl-devel \libselinux-python

  1. 安装Ansible

yum install ansible

  1. 使用pip安装或者升级最新版的Ansible

当前为了更好的兼容kolla,Ansible版本要大于2.4

pip install -U ansible

安装Kolla-ansible

  1. 更改Ansible默认的配置

[defaults] host_key_checking=Falsepipelining=Trueforks=100

  1. 使用pip安装kolla-ansible

pip install kolla-ansible

另外一种方式,使用源码安装kolla-ansible

git clone https://github.com/openstack/kolla-ansible.gitcd kolla-ansible && python setup.py install

  1. 复制yml 和 passwords.yml to /etc/kolla 目录,如果kolla目录不存在,请手动创建。

cp -r /usr/share/kolla-ansible/etc_examples/kolla /etc/

  1. 复制all-in-one 和 multinode资产文件到指定目录

cp /usr/share/kolla-ansible/ansible/inventory/* /home/demo_cluster

准备初始化配置

资产配置

在Kolla-ansible中有两个资产配置文件,all-in-one和mutilnode,这两个文件不同之处是all-in-one在localhost部署单个节点OpenStack,multinode部署多节点OpenStack环境,也就是生产级别的OpenStack环境。

  1. 编辑mutilnode文件
[control]
172.19.1.[10:12] ansible_user=root ansible_password=password ansible_become=true
# Ansible supports syntax like [10:12] - that means 10, 11 and 12.
# Become clause means "use sudo".

[network:children]
control
# when you specify group_name:children, it will use contents of group specified.

[compute]
172.19.1.[13:14] ansible_user=root ansible_password=password ansible_become=true

[monitoring]
172.19.1.18
# This group is for monitoring node.
# Fill it with one of the controllers' IP address or some others.

[storage:children]
compute

[deployment]
localhost       ansible_connection=local become=true
# use localhost and sudo
  1. 生成密码文件,密码文件其实是一组key-value值文件,用于各个组件认证的用户名密码。

密码文件默认存储在/etc/kolla/kolla-passwords.yml中,直接执行。

kolla-genpwd

Kolla globals.yml配置

globals.yml是kolla-ansible非常重要的配置。下面是一些典型的配置选项:

使用哪种发行版的操作系统

kolla_base_distro: “centos”

使用哪种安装包方式

kolla_install_type: “source”

source使用源码方式进行安装,依赖于git

binary使用包方式进行依赖yum或者apt

指定OpenStack版本

openstack_release: “pike”

指定OpenStack版本分支

openstack_release: “master”

如果使用source安装的话,可以指定分支。

  1. 配置网络

配置管理网

network_interface: “eth0”

配置业务网

neutron_external_interface: “eth1”

配置vip,用于keepalived提供高可用。

kolla_internal_vip_address: “10.1.0.250”

  1. 配置额外服务

比如是否启用cinder

enable_cinder: “yes”

  1. 开始部署环境

一旦以上配置完成,我们就可以进行部署,首先我们要设置最基本的依赖,docker。

  • Bootstrap server

kolla-ansible -i ./multinode bootstrap-servers

  • 进行预检查

kolla-ansible -i ./multinode prechecks

  • 开始部署

kolla-ansible -i ./multinode deploy

以上就是部署一套多节点的OpenStack环境,过程比较简单,当时在上文提到,globals.yaml文件是非常重要的文件,所以想要优化部署过程或者使用openstack更高级的功能,应该详细研究每一个参数代表的含义。

生产级Kolla-Ansible

部署生产级别的OpenStack与上述步骤大致相同,但是设置的参数项会很多。

  • 节点角色划分,在生产中,要详细划分控制节点、网络节点、计算节点、存储节点以及监控节点。
  • 网络的配置,为了降低网络的延迟以及网络高可用,那么设置不同的interface是非常重要的,比如network_interface、api_interface、storage_interface、cluster_interface等。
  • Docker相关的配置,在实际过程中,要规划好docker的存储,默认使用devicemapper,所以在生产中要提前做好规划和调研。另外一项是日志,要规划好日志的目录,防止日志过多,导致root崩溃。

作为产品输出

在1.0版本使用了Puppet工具,利用Puppet进行安装,整个过程是流程化安装。Puppet虽然满足现有的部署架构,但是也存在一下缺点:

  1. Puppet工具本身的认证问题。
  2. Puppet的C/S架构,会对用户机器有一定侵入。
  3. 如果考虑到升级维护,必须保留Puppet server。
  4. Puppet很难进行产品化,并且一旦部署过程变动,维护成本也比较高。
  5. Puppet本身学习成本比较高。

综合Puppet一些劣势,我们选择了使用Ansible设计的KubeSpray以及Kolla-Ansible。

如果作为产品输出,不是简单的进行定制开发,产品化的最终用户一定不是自家公司的运维工程师或者研发工程师,而是在大多数人看来,经过简单培训加以文档辅助,都可以完成IaaS设施的部署。

所以,我们将重新设计开发一个自动化部署产品,面向一般用户,简化部署流程,用户只需要填入一些参数以及选择不同的值,就可以完成自动化部署过程。过程不需要干预,并且对过程进行监控,发现问题,及时通知用户。

苏宁云的产品化思路

  1. 依赖KubeSpray和Kolla-Ansible
  2. 设计标准的Restful API,将复杂的用户参数配置以及命令执行,转化为友好的API调用。
  3. 定义WorkFlow,WorkFlow的含义本身具有可编排,Hull定义了多种WorkFlow,用户只需要选择对应的WorkFlow,就可以启动部署流程。
  4. 提供可视化安装,Hull将会提供一套完成的UI操作页面,UI与API耦合度很低。
  5. 封装Cobbler API,使用部署操作系统也加入到整个Hull过程中。
  6. 提供用户管理,即一套平台,可以部署多套IaaS设施。
  7. 同时加入Data Center、Cluster、Region等逻辑概念,更好的满足用户的部署需求。

苏宁云的解决方案

苏宁云新的自动化部署产品Hull给出的方案如下图。

  1. 用户首先进行基本信息注册
  2. 创建data center、region、cluster
  3. 启动WorkFlow,有四种可以选择:
  • Install OpenStack Dev All-IN-ONE
  • Install Kubernetes Dev All-IN-ONE
  • Install OpenStack Pro
  • Install Kubernetes Pro
  1. 控制平台接到部署WorkFlow指令时,启动对应的检查。
  2. 接下来调用IPMI接口进行PXE启动,引导至PXE安装。
  3. Cobbler安装basic OS,比如CentOS7或者Ubuntu16
  4. 安装完成Basic OS后,Cobbler也启动post script进行依赖包安装、内核替换、bond配置、网卡制作等。
  5. 正式安装部署OpenStack或者Kubernetes,接下来过程无需人工干预,在配置正确的前提下,可以自动化完成安装部署。并且安装过程中,会实时向manager平台推送当前安装的进度。
  6. 当安装完毕后,启动Heath-Checker,检查当前安装环境是否正常,比如创建一个虚拟机或者一个pod,并且检查虚拟机的状态或pod的状态。

第三方如何集成苏宁云Hull

  • 统一注册部署管理方式

这种方式所有的集成商,将机器资源统一注册到苏宁云部署管理平台,用户必须登录认证之后,方可操作其下的机器资源。有平台下发部署指令,该种方式要求IPMI IP、物理机器访问均可以被统一部署平台访问。

  • 私有化部署方式

该种方式最为理想,架构类似于在每个客户现场部署一套部署管理平台。

机器启动之后,向指定的manage注册自己。之后由该平台进行统一的指令下发以及部署状态收集。

  • 定制化开发

基于Hull定制化开发也很简单,Hull有独立的Restful API,任何集成商都可以在此产品的基础上再次进行产品化。

作者简介

王晓飞, 现担任苏宁云容器网络架构师职位,在针对Openstack、Kubernetes、swarm网络架构方面有着专业的研究和理解,在该领域拥有超过5年经验,现在负责苏宁云容器网络架构、Openstack网络架构、容器集群监控,主导容器云监控系统开发、容器网络需求定制开发,自动化部署平台,PaaS平台。对DevOps理念有很深的掌握。

孙凯歌,苏宁云高级研发工程师,精通OpenStack,擅长Nova、Cinder、Keystone。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/suning-hull-platform

Electron 3 稳定版正式发布

Electron团队最近发布了Electron 3。最新版本包括很多增强和改进,支持读取海量文件,更好的应用程序管理API以及日志和性能测量功能。

与很多现代软件项目一样,Electron努力发布更多的常规版本,版本之间少一些重大变更。在2.0.0和3.0.0版本之间仅隔了四个月,版本4的beta版本已经在开发当中,Electron旨在为通过Node.js、Chrome和其他现代Web开发API构建桌面应用程序提供快速稳定和改进的平台。

Electron 3的主要依赖更新为Chrome 66.0.3359.181、Node.js 10.2.0和V8 6.6.346.23。

Electron面临的挑战之一是如何区分开发和生产应用。在打包生产版本的应用程序时,新的app.isPackaged属性将返回一个布尔值。

Electron早期版本面临的另一个挑战是如何确定应用程序是否准备就绪。app.isReady()检查Electron是否准备就绪,app.on(‘ready’)用于通知应用程序已准备就绪。创建可以随时调用的源代码需要先检查app.isReady(),如果为false,则订阅app.on(‘ready’)事件。新的app.whenReady()函数通过返回一个promise来封装这个序列,这个promise在Electron初始化完毕之后完成。

为了提供更多性能分析信息,新的process.getHeapStatistics()API返回V8 JavaScript引擎提供的堆测量。此外,新的netLog API提供动态日志记录控制。net.startLogging(filename)和net.stopLogging([callback])用于控制网络日志记录的开始和结束。

随着Electron 3的发布,文件系统访问也得到了改进。fs.readSync现在支持加载大量文件。对文件系统路径的改进包括Node.js文件系统包装器,可以在Electron应用程序中使用fs.realpathSync.native和fs.realpath.native。新的TextField和Button API是添加标准用户界面控件的更大计划的一部分。

Electron 3还改进了用户体验API。win.moveTop()可以将窗口顺着z-order移动到顶部,不会改变用户的输入焦点,以防止意外中断用户。

Electron 3发布公告中提供了Electron 3重大变更错误修复的完整列表。

Electron 4将带来很多改进,可以通过Electron版本摘要查看进度。Electron将继续改进其强大的平台,与其他Web技术一起构建桌面应用程序。

Electron还提供了一个App反馈计划,开发人员可以在测试版发布期间进行早期测试并提供反馈。对于3.0版本的发布,Electron团队要感谢Atlassian、Atom、微软团队、Oculus、OpenFin、Slack、Symphony、VS Code和其他计划成员的帮助。

Electron基于MIT开源许可发行。开发者可以通过Electron GitHub组织参与贡献,并遵循Electron的贡献指南行为准则

查看英文原文Electron 3 Release Increases Stability




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/electron-3-stability

苏宁大促高并发要求下的售后服务运营能力承诺服务系统架构实战

前言

苏宁售后服务运营能力承诺服务系统(简称“ASAP”)是物流研发中心建设的针对苏宁售后服务的时效承诺管理和服务运营能力管理的核心支撑系统,ASAP系统经历两年多的线上考验与技术迭代,目前服务着成万级商家,亿级SKU。

系统定位及核心业务场景分析

首先介绍一下系统的定位,苏宁售后服务运营能力承诺服务系统(ASAP,下称“系统”),是售后服务能力的“库存系统”,主要为售后服务的服务时效承诺和运营服务能力提供管理,与易购商城及线下门店的商品销售及售后服务履约相关联,系统定位为苏宁易购核心销售链路上的核心服务之一。在商品销售和售后服务履约过程,为消费者、苏宁客服、苏宁自营售后服务商、厂家售后服务商和平台售后服务商提供能力服务支撑,为售后服务能力均匀有序的释放提供了系统支撑,从而保障了售后服务质量

然后介绍一下系统的主要功能及业务模式,系统主要提供服务承诺和服务能力的实时接口查询,服务能力的实时增加和扣减接口服务。从业务模式上又分为苏宁自营售后服务、厂家售后服务、平台服务商售后服务,其中苏宁自营售后服务是指由苏宁自营的帮客公司提供的售后服务业务,厂家售后服务是指由商品的原厂商(比如海尔、华为)提供的售后服务业务,平台服务商售后服务是指由平台服务商(比如闪修侠)提供的售后服务,针对这三种业务类型,系统提供全面支撑。

系统的特点

库存系统主要面临以下几个挑战:

  1. 高并发,热点争抢

涉及商品四级页的时效针对同一个商品,比如秒杀、团购、打折促销等活动商品,如何支撑高并发时效能力查询与扣减服务。

  1. 尽可能减少能力超扣,保证数据一致性。

区别与实物商品库存,售后服务能力主要是为了减小下单环节的依赖,能力控制可以放宽限制,服务的能力异步扣除,允许并发情况的少量超扣,但从服务上要保证扣完后的实际能力与查询能力保持一致性,这是底线原则。

  1. 系统扩展性

如何建设出可无限扩展的架构,在系统扩展过程中,各部署节点都需要具备无限扩展能力,而常见的瓶颈如数据库的连接数、队列的连接数等。

架构设计目标

目标

说明

稳定性

保证各种情况下系统的正常工作, 同时需保障原有系统的安全稳定运行。

可扩展性

系统既要满足现有业务的需求,又能适应将来对业务扩展的新需求。

支撑性能的横向可扩展性,只需要增加硬性即可提升性能,以满足业务发展的需要

去中心化

服务能力由相应的业务模块提供,避免服务中心化实现,支持分布式部署架构。

高性能

1)系统接口响应时间:在50ms以内

2 )TPS:7天时效1200tps、45天时效接口8000tps,合计达到20000+

应用架构

业务流程:

1)服务商的运营人员针对服务类型进行服务承诺和服务能力的维护

2)消费者在苏宁易购APP或是网站上选购商品,打开商品四级详情页,调用SOLP进行时效查询

3)SOLP调用ASAP提供的时效查询接口进行查询。

4)消费者完成下单支付,订单由订单中心下发到“售后服务接单管理系统”,由“售后服务接单系统”调用ASAP系统进行能力扣减。

5)如后续的售后服务订单有取消或另约服务时间请求,则会调用ASAP的能力的回滚接口进行能力回滚。

系统架构

ASAP架构主要涉及:

1)ASAP服务:主要提供能力的加减服务包括能力新增和能力扣减接口,

2)ASAP后台:主要提供系统给运营人员进行承诺和时效服务的

3)中间件:主要涉及分布式服务框架RSF、任务调度平台UTS、消息队列WindQ

4)数据层:主要用到了Redis集群,mysql数据库集群。

5)基础服务:主要依托苏宁的基础DEVOPS工具链完成开发和运维工作。

技术框架

开发框架

系统采用苏宁SNF技术框架开发,苏宁SNF框架基于MAVEN项目管理,提供各种的骨架组件。在这些骨架组件中,基本的依赖和基本设置都在模板中做好,无需各项目重复工作。本框架也包括了基本的项目框架结构和各种基本设置,同时也集成了苏宁框架组统一的日志记录、异常捕获、数据访问等苏宁自己的基础组件。

项目组在SNF框架的基础上,进行少量的裁剪和扩充就可以进行开发,既能统一项目设置和架构,又能大量节省开发人员搭建框架的时间。

开发环境

STS+Maven+SVN +JDK1.7+JBoss。

分布式服务框架RSF

系统提供的核心的服务接口均采用苏宁自研的RSF框架实现,RSF框架 解决了分布式系统间的服务调用问题,提供一种透明的、高性能的RPC服务调用方案。

主要功能:

  • 支持同步、异步Future、异步Callback三种客户端调用模型;
  • 支持TCP协议及Hessian、JSON、KRYO序列化机制;
  • 服务节点的自动注册和发现;
  • 多种负载均衡方式;
  • 服务路由;
  • 容错重试机制;
  • 流控,熔断等机制;
  • 统一的服务配置管理,支持配置的动态修改。

总体架构:

系统面临的挑战及应对

虽然系统采用了SNF框架,基于苏宁组件和基础设施,搭建了高并发的分布式架构,但随着苏宁易购电商业务高速发展,订单屡创新高的背景下,系统依然面临一些挑战:

  • 扩展痛点:受限于数据库的连接数瓶颈、Redis服务器的连接数瓶颈等因素,导致应用集群无法无限扩展;
  • 机房容灾及机房容量:机房断电,电缆被挖,造成整个苏宁易购交易系统瘫痪;单个机房容量受限,无法创建更多的服务器;
  • 热点瓶颈:虽然通过构建缓存化支持能力服务,但单个商品的并发查询和扣减仍然存在上限

为了解决上述问题,我们启用了应用的本机分布式缓式,并在公司规划下正在进行多活架构构建。

应用服务器内存缓存

我们通过Ehcache框架,对于一些配置主数据和能力总量在应用服务器进行内存缓存,从生产压测情况来看效果明显,在不新增服务器的条件下tps成倍增加,redis热点消失。

后续也计划对于已约数量等实时能力数据,通过分布式缓存实现共享,以进一步提升单个商品并发查询和扣减的热点瓶颈。

多活架构

目前ASAP系统在公司统一部署下实现了多活的支持,在多个机房之间建立数据库和Redis缓存数据的准实时同步,支持多个机房间的流量切换,当A机房出现故障,可由B机房完全接管,具体多活的生产应用还在联调中。

双11等大促活动保障

经过两年多的大促实战,基本形成了事前、事中、事后完整的大促保障工作机制,工作项标准化,越来越细致,组织上有专人牵头负责具体工作项事务,形成了完整的闭环。

容量和性能评估

对公司双11大促的 活动预告及销售目标进行详细评估和分解,转化成ASAP系统的核心服务的SLA,确定库存系统的核心服务的TPS目标。

性能压测达标

大促前,我们会进行多轮的生产压测,最重要的是单系统的接口压测和端到端全链路压测。通过单系统服务接口压测,我们排除接口潜在的性能瓶颈并针对性的优化,能够清楚认识负责系统的单接口所能支持的并发上限;通过生产真实流量回放的端到端全链路压测平台,进行全链路的生产压测,发现真实流量下的系统压力情况,和资源情况,提前发现性能瓶颈和潜在的系统风险。性能测试是大促筹备最为关键的一环。

系统健康体检

提前对系统的各方面进行全面的健康检查,比如db磁盘的容量、连接数、topsql,缓存的内存使用率、并发命令数和连接数,消息队列的连接数,各节点的cpu负载情况,排除单点故障,排除虚拟机的资源争用问题,排除高可用问题(同一物理机多应用节点)等。

机器扩容

基于容量预估出来的各服务接口的TPS目标,根据压测结果评估系统的服务器是否需要扩容,比如jboss集群是否需要扩容,redis集群是否需要扩容,数据库服务器性能是否有足够等。

梳理流控与降级方案

所有服务接口需要设定合理的流控阀值,以确保系统不会挂死;梳理所有接口的调用系统和业务场景并明确业务的优先级,假设系统因为某服务导致性能出现瓶颈,根据业务优先级逐步调整流控阀值;业务流控或系统流控要实现用户的友好提示;对于依赖系统,如果出现超时或宕机,则定义降级策略,确保服务请求的快进快出。

作者简介

汪成伟,苏宁易购IT总部物流研发中心技术总监,目前负责苏宁物流研发中心售后相关系统的架构与开发管理工作,具有十多年互联网一线研发及管理经验。曾负责过B2C电商平台、移动新闻资讯平台,用户上网行为分析大数据平台及O2O社交应用的研发工作。是DevOps的践行者,在企业应用架构设计、高并发系统设计、大促保障、研发过程管理、稳定性治理、安全开发上有丰富的经验。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/suning-after-service

苏宁11.11:搜索引擎Solr在苏宁易购商品评价系统中的应用

背景说明

苏宁易购商品评价系统主要提供商品维度评价数量聚合、评价列表展示功能,并为其他业务系统提供商品评价数据支撑服务。功能涉及对亿级数据的数量聚合、排序、多维度查询等复杂的业务场景,关系型数据库的索引为B-Tree结构,适合数值区分度或离散度高的数据,而评价系统中单个商品评价可以达到数十万条,相同星级的评价数则为亿级,故不适宜使用关系型数据库。解决此类海量数据准实时聚合的技术选型有以倒排表作为索引结构的Solr和Elasticsearch(底层都是Apache Lucene)搜索引擎服务,还有以bitmap作为底层索引结构的实时分析统计数据库Druid,但Druid只是支持数据统计功能并不保存原始数据,无法满足商品评价类的功能需求。系统建设之初对团队对Solr更为熟悉,故在Solr和Elasticsearch两者之间选择的Solr作为商品评价索引数据存储服务。

评价系统架构

苏宁易购商品评价系统架构如下:

image

图2-1

应用服务模块

根据苏宁易购技术规范要求,应用系统架构划分为前中后台三个主模块:

  • 前台:为web、app提供页面或接口服务,接入苏宁统一认证系统Passport;
  • 中台:通过苏宁自研RSF远程服务框架对前台服务和其他业务系统提供功能接口服务;
  • 后台:业务系统运营管理功能和任务批处理。

数据存储层

  • MySQL:存储和查询登录用户发表的评价,具备ACID特性,按照用户ID分库分表,根据业务要求和存储容量限制只保留指定时间内的评价数据
  • Redis集群:苏宁在开源Redis中间件基础上自研的支持分布式集群、熔断、横向扩容的高可用、海量缓存服务架构,缓存商品评价数量和列表数据,承载用户端的数据访问请求,降低对业务系统的访问压力
  • HBase:海量评价内容存储
  • Solr:评价索引存储和查询服务

外围系统

  • 商品中心:通过MQ(异步)和RSF(同步)接收保存商品主数据如商品信息、类目信息、店铺信息、商品关系信息等
  • 订单中心:待评商品主要来源于订单中心通过MQ下发的订单信息和订单状态通知,并由评价系统提供订单待评状态查询RSF接口,在订单页面展示商品评价发表入口
  • 搜索产品线:通过MQ下发商品评价数量到搜索产品线,为商品搜索排序计算提供数据支持

基础设施

  • 分布式任务调度系统(UTS):对各业务系统中的定时任务进行集中管理和调度,解决了集群环境下任务并发执行的控制,让业务系统从繁琐的技术细节中释放出来,并提供了对任务调度执行情况的监控和异常短信告警、重试机制,且提供跨业务系统的后继任务调度。
  • 集中配置管理(SCM):基于Zookeeper自研的应用配置信息集中统一管理和实时推送服务框架。
  • 消息中间件:由于历史原因,苏宁内部有多套MQ中间件,包括IBM MQ,Kafka和自研的WindQ。IBM MQ已经不建议使用,正在逐渐废弃;Kafka在大数据场景下使用较多;业务系统推荐使用WindQ,解决了解决多活场景下消息路由,提供消息发送重试熔断、在线动态扩缩容、顺序消费、异构MQ桥接等特性。

监控

  • 日志:改造Solr日志模块,接入苏宁统一日志框架,便于异常问题分析
  • 主机:接入Zabbix监控体系,监控主机和应用健康状态
  • 系统:接入苏宁云迹系统,监控Solr请求响应TP90/99等指标

Solr介绍

搜索引擎基础原理

搜索引擎的索引称为反向索引,俗称倒排表,把文本分词得到字典,保存字典项与文档ID(Lucene自身doc ID而非应用端文档ID)的关系,在查询时根据字典查询到倒排表文档ID集合,再进行交并集操作即可得到结果,其主要结构是字典域、索引域和字段存储域。反向索引如下图:

image

图3-1

在Solr4.0之后为了满足排序和关键字聚合的需求场景,Lucene提供了DocValues特性,又被称为正排表,使用列式存储保存文档ID和字典项的关系,不再使用之前FieldValue Cache机制,提升性能并降低对内存的使用和虚拟机Full GC的风险。在Elasticsearch中所有字段都是默认开启此特性,但在Solr中需要使用者进行显式配置生效。DocValues存储结构可分为两种,一种是原值,一种是字典项ID。

  • 单数值型和原始字节型字段,其基本结构包含字段原值的long[]数组,如带有三个数值的文档DocValues结构:
doc[0] = 1005 
doc[1] = 1006 
doc[2] = 1005
  • 其他可索引类型字段,其结构也是一个long[]数组,只不过数组中的值为字典项ID(可能有多个),例如有3个字符型字段的文档:
doc[0] = "aardvark" 
doc[1] = "beaver" 
doc[2] = "aardvark"

假如“aardvark”在字典表中ID为0,”beaver”在字典中ID为1,则实际结构为:

doc[0] = 0 
doc[1] = 1 
doc[2] = 0

字典表数据为:

term[0] = "aardvark" 
term[1] = "beaver"

注:字典表所有term都是有序的,故DocValues可以直接用于排序。

Solr&Lucene架构体系

Solr是一个高性能、基于Lucene的开源全文搜索服务,提供丰富的查询语言,同时实现了可配置、可扩展并对查询性能提供了优化,提供完善的功能管理界面;在Lucene基础上对易用性和可用性进行了大量封装如Schema配置化、请求分发处理机制、插件化机制、数据导入、分布式、监控指标采集等,架构体系如下:

image

图3-2

苏宁商品评价系统结合自身业务特点采用了Solr主从节点和聚合查询节点的组合架构,而不是通用的Solr Cloud架构,主要考虑到两点:

  • 横向扩容机制完全可控,根据商品编码单调递增特性,可以随时扩充新节点,节点路由机制由业务系统控制。
  • 单独搭建聚合查询节点,在跨多个Solr节点查询时由聚合节点实现聚合查询功能,特别是在聚合商品评价列表查询场景下,降低对数据节点的性能压力。

Solr特性应用

多维度数量聚合

商品详情页展示商品/供应商维度审核通过的好中差评数量、标签数量、个性化评价项等数量,使用的是Solr facet机制。

image

图4-1

  • 单个字段facet如好中差评数据量(上图方框处)涉及星级字段直接设置facet.field参数 /solr /select?q=*:*&wt=json&indent=true&facet=true&facet.field=qualityStar

  • 多条件facet如有图评价和已追评(上图圆圈处)评价数量,应使用facet.query机制把每个facet.qery查询当做单独facet值,一次性查询出结果而不是发起多次普通总数查询

/solr/select?q=*:*&wt=json&indent=true&facet=true&facet.query=picVideoFlag:1&facet.query=againReviewFlag:1

多维度列表查询

根据查询条件直接查询评价ID即可,限制查询字段并支持分页,因商品评价无需计算文档相似度且开启缓存可提升查询性能,故使用filter query替代query作为查询条件:

/solr/select?q=*:*&fq=(auditStat:0+OR+auditStat:1)&start=0&rows=10&fl=commodityReviewId

需要注意的是filter cache是以单个filter query为键缓存结果,可以根据业务需求要求拆成多个filter query,设置不同缓存策略以提升缓存利用率。

分组查询

需要说明的是Solr分组关键字group的含义与关系型数据库的group by中的group并不相同,在Solr中指的是对查询的结果文档根据指定的字段进行分组,而非关系型数据库对字段分组,如苏宁商品评价需要展示每个评价的第一条商家回复内容,通过Solr查询商家回复并根据评价ID进行分组后取第一条记录即可(查询条件为评价ID列表),参数说明如下:

image

表4-1

自定义排序

在使用Solr对结果集排序一般有两种方式:

  • 一是在写入索引时单独字段保存数值,在查询时使用sort字段直接排序即可,优点是简单,但调整排序规则时需要重建所有索引。

  • 二是函数查询机制,在Solr标准查询解析器中使用solr内置的函数,指定sort字段为函数内容或在DisMax中指定bf参数都可以满足业务需求,例如sort=div(popularity,price)desc,score desc格式,div函数表示popularity和price两个字段相除。

大部分排序都使用第二种方式,但此方式对性能会有影响,特别是在涉及到多个字段时且参与排序的文档数较多时,其内部执行过程需要获取每个匹配doc的字段值进行计算,即使字段开启docValues特性对存储、IO和内存空间也有一定压力。

提升函数排序的性能也有两种方式:

  • 一是粗略的计算排序值,或写索引时即有一定顺序,查询时进行截断,只返回一定数量的文档,再进行二次排序,即通常电商搜索中粗排和精排过程。
  • 二是把涉及到的排序字段合并到一个字段并开启docValues特性,例如【评价时间|会员等级|评价星级|内容长度|图片个数|内容质量分|图片质量分|人工审核权重】此种格式,并编写自定义函数解析计算这个组合字段的排序值;继承org.apache.Lucene.queries.function.ValueSource实现排序值计算,继承org.apache.solr.search.ValueSourceParser实现此函数的解析创建即可。这也是苏宁商品评价系统准备采用的方式。

facet.method参数的选择

Lucene字段级facet有三种机制:

  • enum:遍历字段下所有的字典项,对所有字典项的倒排文档ID和查询结果文档ID进行交集运算得到结果
  • fc:根据查询结果的每个文档ID从Field Cache中查询字段值,计算每个字段值的次数得到结果
  • fcs:类似于fc,不同点是基于Lucene中每个段单独的Field Cache

facet.method参数指定在对字段进行聚合时使用上述哪种算法,根据上述实现机制说明可知对于值区分度低的字段,适合选择enum机制;对于有大量不同值的字段合适使用fc机制,若Solr开启了近实时搜索(NRT)特性,fcs机制则是更好的选择,因其在生成新索引段时旧索引段缓存不用重新加载。

分布式聚合查询

苏宁易购商品电商模型中SPU和SKU可以在商品上架时根据产品特性和销售情况动态调整组合,查询SPU商品评价时就会出现跨多个节点的场景,需要支持跨节点的分布式查询并对聚合结果集进行二次处理,如数量的累加、列表二次排序和分页等,为此搭建空数据的Solr节点作为聚合查询节点。业务方根据SPU和SKU关系得出节点编号和节点的地址,改写查询请求添加shards参数转发给聚合节点即可,示例如下: /solr/select?

q=*:*&wt=json&indent=true&facet=true&facet.query=picVideoFlag:1&facet.query=againReviewFlag:1&shards=solr1:8080/,solr2:8080/,solr3:8080/

此特性原理是使用多线程查询多个Solr节点,在内存中对结果进行合并,故使用此特性也有一定限制:

  • 列表分页须限制大页码,防止列表合并分页时内存溢出或产生Full GC问题,性能急剧下降并可能拖垮服务节点
  • 相关性排序和facet特性可能与单节点查询结果可能不同
  • 注意设置线程池数量和HTTP超时时长
  • 文档在所有节点必须唯一,不允许重复
  • 不支持pivot facet和join特性

性能调优

  • 开启filter cache,以查询条件为key,文档ID列表为值保存在cache中,可以大幅提升数量聚合性能,但需要注意不适合字段值离散度较高的查询,否则产生大量key会把cache中的热点缓存替换出去,缓存命中率下降反而影响性能,可以通过设置cache=false或在函数查询中设置fq={! cache=false}参数屏蔽当前请求的cache机制

  • 文档数较多且命中率低,需要关闭documentCache和queryResultCache

  • 设置newSearcher和firstSearcher两个Listener的查询语句,对重新打开的IndexSearcher进行预热

  • JVM使用CMS GC策略,并设置CMSInitiatingOccupancyFraction值为60,保证在主从同步时Solr有足够的堆内存,降低因CMS GC内存碎片导致Full GC的风险。

配置示例如下:

<query>
	<maxBooleanClauses>2000</maxBooleanClauses>
	<filterCache class="solr.FastLRUCache" size="8192" initialSize="4096" autowarmCount="80%" />
	<enableLazyFieldLoading>true</enableLazyFieldLoading>
	<listener event="newSearcher" class="solr.QuerySenderListener">
		<arr name="queries">
			<!-- 预加载查询 -->
		</arr>
		</listener>
	<listener event="firstSearcher" class="solr.QuerySenderListener">
		<arr name="queries">
			<!-- 预加载查询 -->
		</arr>
	</listener>
	<useColdSearcher>false</useColdSearcher>
	<maxWarmingSearchers>1</maxWarmingSearchers>
</query>

展望

目前在CDN缓存和Redis缓存失效情况部分请求的压力还是回源到Solr,对于Solr的直接依赖较大,且更新索引时偶尔还是会触发Full GC,影响业务的稳定性。下一步需要对缓存架构重新设计,设计缓存异步更新和熔断机制,限制用户请求直接落到Solr服务上,提升接口QPS、系统稳定性和评价展示生效实时性。

另外还在规划引入Elasticsearch作为后台业务索引,前后台索引进行分离,降低前后台耦合度和系统风险,更便于业务开发。

作者介绍

胡正林,苏宁易购IT总部消费者平台研发中心高级架构师,十余年软件开发经验,熟悉大型分布式高并发系统架构和开发,目前主要负责易购各系统架构优化与大促保障工作。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/suning-search-solr

阿里巴巴华先胜支招:如何从技术和应用层改进视觉搜索?

导读:视觉识别和视觉搜索是视觉智能中两项最为常见和重要的任务。基于内容的图像检索技术——视觉搜索由于应用前景广阔、能为用户带来更便捷、更优化的体验而越来越受到研究和应用领域的青睐。然而,在技术和应用层面,虽然视觉搜索在有些领域取得了巨大突破,在更广泛的领域还面临着诸多挑战。阿里巴巴视觉智能计算团队重点研究的“城市大脑”项目,就在视觉搜索技术上拥有很多落地实践和克服困难的经验。他们踩过哪些坑呢?对于视觉搜索这项技术,他们的看法是什么?

视觉搜索,又称基于内容的图像检索,成为近年来计算机视觉的一个热门研究领域。视觉搜索不同于文字搜索,可以以图像的形式直观地搜索所需内容,因此在社交媒体、电商搜索等实际应用场景中非常受欢迎,如社交软件Snapchat上线了“相机搜索”,通过这一功能,用户可以长按识别图片或短视频中的商品、歌曲、条形码等;eBay、淘宝、京东等电商平台也纷纷推出图片搜索功能,用户可以通过拍照找到想要的商品,提高搜索效率,提升用户体验。

阿里巴巴视觉智能团队的重点研究方向“城市大脑”项目,就包含了基于图像搜索的技术而达到“智慧城市”的目的,并且在落地场景中获得了很多经验和突破。

据悉,阿里巴巴视觉智能计算团队目前的重点在四个方向:城市大脑,医疗AI,工业视觉和智能设计**。其中“城市大脑”致力于通过云计算和人工智能技术去解决依靠人脑无法解决的城市治理和发展问题。围绕这一目标,阿里巴巴目前的重点研究方向包括:多模态城市感知、交通预测与干预、并行异构计算加速、基于视频的行人与行为搜索识别、大规模城市视觉计算平台等。

基于视频的城市对象感知几乎是所有工作的基础,也是阿里率先取得突破的技术方向之一。在过去一年,阿里巴巴视觉智能计算团队先后取得了KITTI(全球权威机器视觉算法排行榜)比赛中车辆检测和行人检测两项测评的冠军。在行人再识别任务中,也在公开数据集Market-1501上取得了当前最好成绩(97%首位命中率),并在实践中得以广泛应用。

阿里巴巴在其他方面,如深度模型压缩等也有突破。智能设计当中最为突出的是电商场景的二维广告图设计,基于深度学习和强化学习的方法,可以高效地设计出初级设计师水准的广告图,并在双11等场景中得以大规模应用。

“城市大脑”如何工作?

阿里巴巴的“城市大脑”项目需要处理整座城市的海量数据,这一挑战的难度可想而知。

“城市大脑”是如何处理整个城市的视频数据呢?使用到了哪些计算机视觉AI算法进行优化和决策?

城市大脑人工智能技术负责人华先胜为我们揭开了谜底:“简单来讲,城市大脑可以分为这么几个步骤,首先是数据的汇聚,通过数据管道将各个部门的数据汇聚到我们的数据平台上来。第二步是数据的认知,当然其中主要是视频数据要通过我们的认知平台进行认知,要把整个城市发生的事情了解的一清二楚。这其中包含的视觉算法很多,从常见的分类、检测、跟踪、分割,到特征学习、视觉检索、异常检测等等都会用上。第三步是在认知的基础上,进行**决策和优化**。当我们对城市的整个交通状况有了了解之后,我们就可以进行红绿灯配时的优化,或者交通事件、事故的实时报警。在前面几步的基础上,第四步我们把城市的要素,车、人、事、物全部放到搜索引擎里面去,进行快速的查找。例如对肇事车辆、特定目标的查找。当然也可以挖掘这些数据的联系,从而发掘事故事件以及一些交通现象背后的发生的原因。第五步是**预测**,预测城市的发展趋势是什么样子的。比如说半个小时以后路口的车流或者一个大型商场周边的人流的情况。第六步是干预,因为有了预测以后,我们就可以进行对应的处理,例如说如果我们知道一个小时以后的人流和车流会出现显著地增加,那我们可以提前部署紧急人力甚至是医疗资源来应对一些突发的事件。”

总结来说,从数据汇聚、数据认知、决策优化、搜索挖掘、预测到干预,整个一条流程是整个城市大脑的主要功能的体现。华先胜还透露,这些功能都是基于一套大规模视觉智能计算开放创新平台而得以实现,而这个平台在刚刚结束的杭州云栖大会上对外发布,近期会开放出来,让更多的人能够在城市这个规模进行视频的分析和视频大数据的价值挖掘。

华先胜表示,实时处理整个城市的视频数据确实是一个非常艰巨的任务,团队遇到的主要困难之一是计算资源的消耗。“即使我们已经拥有云集群、GPU等很强的算力,但是如果不经过任何优化,在合理的机器成本下,依然无法实时处理整个城市的海量视频数据。因此我们从多个方向发力来解决这个问题,首先是模型的精简和加速,众所周知深度学习模型的通病之一是参数量大、推理时间长,因此我们利用了矩阵分解、稀疏量化等技术进行模型精简和加速。其次我们也和Intel、英伟达等硬件厂商进行深度合作,从底层硬件角度进行计算加速,将硬件的性能发挥到极致。再者,在单个计算节点上的调度,也是提升整体效率的有效方法。另外,我们也开发了基于流式计算平台的智能调度模块,通过并行处理、弹性调度等方式进行处理流程优化。这些技术将单台服务器的处理能力提升了20多倍。同时我们也在布局低成本的解决方案,比如专用FPGA芯片等。”

图像搜索如何改进?

图像搜索是计算机视觉、多媒体领域的一个很经典的问题,近些年随着深度学习算法的发展,这个领域也取得了很快速的发展,但是随着实际应用场景的扩展、数据规模的扩大,也有很多可以优化的地方。

那么,阿里巴巴是如何从技术层面和应用场景层面上改进图像搜索技术的呢?

华先胜表示,阿里巴巴曾在三年前克服了很多技术难题,研发出商品拍照搜索应用“拍立淘”,而城市视觉元素的搜索,因其数据的复杂度和数量,则是更为困难的一个问题。

“从技术层面来说,首先我们需要一个更好的特征模型,来学习细粒度的图像特征。除了目前比较火的local feature、attention等技术外,一个比较有趣的方向是,在特定的图搜任务下,如何引入一些人类的先验知识,比如车辆的刚体结构、人的骨架信息等等。其次,视频数据会比图像数据具有更丰富的表征,如何利用视频数据进行检索也是一个很有潜力的方向。

基于深度学习的图像搜索依赖大量的标注数据,这其实很大程度上限制了算法在实际应用场景下的扩展,如何利用半监督、弱监督、无监督算法提升算法性能是一个关键问题

其次真实场景下的数据规模很大,在海量的图像库中进行欧式距离的计算会带来很高的延时,限制了算法在实时场景下的应用,因此高效的向量索引技术也是在实际场景中落地的必备组件。”

由此可见,图像搜索技术还有很多有待提升的空间,有望改进搜索精度不够、搜索结果不匹配等在实际应用中经常出现的问题。

华先胜认为,未来,视觉搜索在众多场景中具有非常大的商业化潜力,城市大脑就是一个很大的应用场景。

“城市对象的感知其实是城市大脑的一个基础组件,而城市对象的视觉特征提取就是感知的重要组成部分。通过对城市对象进行特征提取,我们可以在海量的数据中搜索出特定目标的移动轨迹。在交通场景下,可以帮助我们构建精确的车流、人流数据,从而服务上层的流量预测与干预应用。阿里巴巴的渐进式视觉搜索引擎已经在衢州投入使用,可以帮助有关部门寻找走失人口,保障平民生命财产和资源安全。”

讲师简介

华先胜,现任阿里巴巴集团Distinguished Engineer,副总裁,阿里巴巴人工智能核心研发机构达摩院机器智能技术实验室副主任,城市大脑人工智能技术负责人。华博士是美国电气与电子工程师协会会士(IEEE Fellow),美国计算机协会杰出科学家(ACM Distinguished Scientist);2008年获MIT技术评论“全球35个35岁以下杰出青年创新者”称号(TR35)。1996年和2001年毕业于北京大学数学学院,分别获学士和博士学位;之后分别工作于微软亚洲研究院,微软美国必应搜索引擎,以及微软美国研究院,从事多媒体、计算机视觉和机器学习方面的研发工作。2015年4月加入阿里巴巴,任搜索事业部资深总监/研究员;2016年加入阿里巴巴iDST,负责云上视觉智能计算的技术研发。他的研发兴趣在大规模视觉人工智能领域,包括视觉分析、识别、搜索和挖掘等。华博士在国际主流会议和期刊上发表论文200余篇,拥有专利90余项。曾担任多个学术期刊的副主编以及ACM Multimedia等顶级学术会议的程序委员会主席,并获得多个国际会议及期刊的最佳论文奖。华博士将担任多媒体智能领域顶级国际学术会议ACM Multimedia 2020年大会主席。

华先胜将会在12月份AICon大会上担任联席主席,想要跟华老师进一步交流的童鞋可到现场面基。

另外大会还邀请到了来自Google、Twitter、Netflix、BAT、360、京东、美团、小米、今日头条等40+国内外一线AI技术负责人前来分享他们的机器学习落地实践经验,除此之外,还有知识图谱、NLP、语音识别、搜索推荐、计算机视觉、AI架构等热门技术,干货满满。

目前大会6折售票倒计时4天,团购更优惠,点击这里了解更多详情。如有任何问题,可咨询票务小姐姐:18514549229[微信同号]




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/alibaba-visual-search

苏宁中间件配置巡检效率提升之路

1、前言

苏宁易购发展到今天的规模和体量,对苏宁IT提出了更高的要求,特别是在运维方面,提出了更高的响应和保障要求,整个运维体系也是在不断提升自动化处理能力和水平,为苏宁易购的快速成长做好后端保障。

在中间件运维方面,我们开发了相应的中间件运维工具支撑大规模的中间件配置及巡检,提升配置标准化的能力和系统稳定性。在工具的建设过程中,我们不断探索新技术,提升对大规模运维的并发处理能力。在WildFly的配置巡检上,我们取得了较大突破,实现了效率和性能的双重提升。

2、配置巡检配置巡检目的

从系统上线到运维,从手工配置到自动化配置,多部门协同工作,导致出现各种配置不一致、不标准、甚至缺失的情况,这些运维中的痛大家都遇到过,配置巡检是运维必不可少的一项工作,对于我们来说,检查点在以下几方面:

1、应用中的数据源连接池最大连接数是否超出数据库配置的最大连接数; 2、应用中数据源是否配置了数据库的高可用方式; 3、数据库主备配置的最大连接数是否一致; 4、废弃的数据源配置是否从环境中删除; 5、JMS是否配置了主备信息。

这些检查是要保证我们的配置无误,对应的主备、高可用配置检查,都是为了确保后端数据库发生宕机做主从切换后,前端应用可用自动恢复,无需人工干预,尽快恢复系统的可用性。对应的数据源连接池的大小配置,也是为了保证数据库的安全,避免应用与数据库的连接过多引起数据库的故障造成较大的影响。

我们现在应用服务器数量比较多,架构也存在多种,人工巡检已经不现实,工作量太大,效率、准确性都无法保证,我们只能往自动化巡检方面发展。

在我们目前使用规模最大的WildFly方面,我们经过一段时间的发展,在自动化巡检方面探索出了更为高效的方法,提升了我们整个中间件配置巡检的效率。

3、自动化配置巡检发展之路

由于WildFly官方文档比较少,能参考的不多,我们在负责中间件运维的同时去开发运维工具,时间太碎片化,进度方面难以保证,经过三个阶段的发展,终于找到了高效的方法,实现了我们一个小目标,我们一直痛并快乐着。

3.1阶段一:cli方式获取,手动校验

3.1.1介绍

现在生产环境规模比较大,仅WildFly虚机已近30000台,我们使用python开发了批量巡检的脚本,并实现web化管理,方法如下:

1、将通用的python配置巡检脚本传输到每台服务器上; 2、脚本中调用本地jboss-cli.sh命令去获取jboss的相关配置信息,包括jdbc、jms等配置,因涉及多项配置信息,循环获取详细配置属性,需要调用本地jboss-cli.sh命令次数不定; 3、Python脚本将获取的原始配置数据整理成json数据,然后将json数据返回到本地脚本,入库保存; 4、再跑不同的脚本去解析详细的配置数据以及核查配置,最终导出到Excel文件供运维人员逐一核查处理。

Jboss-cli方式可以很方便的获取到格式化的配置信息,也可以在线进行jdbc、jms等配置,可以实时动态的修改日志级别,用起来可谓是优势显著,既提升效率又不虞有修改配置文件出错的顾虑,是自动化、标准化实施配置的极佳选择,而且在文档极度缺失的情况下,这个命令在写的时候可以自动补全和提示,极大的方便了我们去获取我们需要的信息。

3.1.2效果

这个方法可以核查出大部分的异常配置数据,是自动化的第一步,降低了运维人员手工核查的工作量,将工作精力放在存在问题的配置核对和修正上,收效明显。

3.1.3缺点及问题

1、由于jboss-cli本身执行的问题,容易出现配置获取缺失的情况; 2、数据源连接数计算不是非常精准,容易出现偏差; 3、这种方式获取一次,并完成解析和校验,在不限制线程数量的情况下仍然需要5个小时以上,效率比较低; ……

3.2阶段二:cli方式获取,自动校验

3.2.1介绍

之前的方法存在各种使用上的不足,自动化程度、效率有待提升,导致我们只能在每次大促之前的一段时间批量处理一次,这就导致每次大促前会检查出很多配置需要修正的情况,要么修改数据源配置,要么修改数据库连接,这样非常不利于系统的稳定,而且这种集中式的处理也增加了项目组和运维人员的工作压力。

我们调整了整个配置获取、解析、核查的方式,在配置获取完成后直接在线程中解析详细配置以及计算连接数,解析和计算完成后直接将结果入库,将存在问题的配置数据展示在前端页面,便于运维人员随时查看和处理。

3.2.2效果

这种方式极大的提高了单次配置获取、解析、核查的效率,并将核查频率由之前的每次大促前一次提高到每周一次,便于运维人员在平时就可以修正配置,将大促前的一次性工作改变为日常的运维工作,在日常工作中解决风险,是运维模式上的一次较大的改变。

3.2.3缺点及问题

1、这种方式仍然没有解决数据计算不精确的问题; 2、jboss-cli.sh命令会在本地启动一个将近80MB的独立进程,脚本中循环调用该命令,会在短时间内频繁的新建这样的进程,会造成机器大量的性能损耗,我们只能放在夜里跑任务,也经常有项目组找到我们询问服务器CPU在夜间告警的问题; 3、单次全量获取和解析速度依然无法满足我们的需要。

就是WildFly这么一种自带光环的配置方法和工具,在实际使用过程中却出现了瓶颈,在执行的时候会启动独立的进程,而且对CPU资源消耗较高,在后面的测试对比中有数据说明,这样的结果让我们的应用场景也受到了限制,不能影响业务系统本身的资源使用,将数据抽取的任务放在凌晨业务低峰期的时候进行,频率只能一天一次,遇到大促这种场景,还得暂停任务,将资源全部让给业务系统。

3.3阶段三:http获取,自动校验

3.3.1介绍

我们总结了之前的问题,集中在服务器性能的消耗和效率上,我们开始研究新的配置获取方式:

1、不再使用jboss-cli的方式去获取配置信息,而是采用http的方式,以降低服务器性能损耗; 2、由于使用了http方式,连接数的计算也不再依赖本地数据,全部基于jboss获取的数据信息,以提升数据的计算精度。

但是官方网站的doc文档对HTTP+management+API的描述极为简单,仅有为数不多的文字描述和和寥寥无几的样例,查遍第三方技术论坛几乎没有任何相关资料,因此每一个http的接口都需要我们慢慢尝试和探索。

根据官方的doc文档我们知道:

1、HTTP+management+API包括GET方式和POST方式2种; 2、HTTP+management+API符合REST风格; 3、接口需要用户名和密码; 4、接口需要设置头信息。

根据这些信息,我们一开始只推测出一些post方式的配置查看的API,但是我们业务需求只需要获取配置信息,无需传递数据去新增、删除和修改配置,所以不太适用于我们的业务场景,而且使用这种方式有明显的缺陷:每个配置项都要单独调用一次http请求,对于jdbc和jms的每个自定义属性也都要单独调用http请求去获取。这种方式仍然需要N次调用接口,依然需要消耗服务器的性能,所以转而去探索GET方式获取配置信息的方式。

终于在不懈的探索和尝试之后,我们把获取standalone模式的单个节点全部jdbc、jms配置的所有信息的HTTP+management+API的调用次数压缩到了3次,domain模式的压缩到了不超过5次。而且接口调用返回数据几乎是秒回,效率提升非常显著。

3.3.2接口介绍

3.3.2.1接口简介

获取概要信息:此接口可以获取部署的应用包、节点信息和组信息等 curl --digest 'http://username:password@ip:9990/management'

获取所有数据源详情:此接口可以获取该WildFly上配置的所有数据源的所有信息,包含自定义属性和值,如果不需要详细信息可以去掉recursive这个参数。

curl --digest 'http://username:password@ip:9990/management/subsystem/datasources/data-source?recursive'

获取所有MQ队列和MQ队列工厂数据:(wmq.jmsra.rar是IBM MQ驱动包文件),这个参数可以获取该WildFly上的所有MQ队列和队列工厂的数据,如果不需要详细信息可以去掉recursive这个参数。

curl --digest 'http://username:password@ip:9990/management/subsystem/resource-adapters/wmq.jmsra.rar?recursive'

对于domain模式的集群只要在management/subsystem之间添加一个profile的信息(profile/$profile),如此即可: curl --digest 'http://username:password@ip:9990/management' curl --digest 'http://username:password@ip:9990/management/profile/$profile/subsystem/datasources/data-source?recursive' curl --digest 'http://username:password@ip:9990/management/profile/$profile/subsystem/resource-adapters/wmq.jmsra.rar?recursive'

3.3.2.2 参数说明

目前实验出来的并且知道作用的参数:

image

3.3.2.3 探索过程分享

在经历了一段时间的盲目并且不懈的探索后,发现这种接口探索效率低下,收效甚微。而且在技术论坛也查找无果的情况下,我们想到cli方式和http接口方式的底层处理方式应该是一致的,所以接口的层级关系应该也是相似相通的。所以希望借助cli自动提示和补足的功能,探索每个数据项的层级关系,这样可以逐步知晓HTTP接口的层级关系。实际情况是这种方式确实有一定用处,但是随着摸索工作进一步深入才发现:两种接口方式还是有较大区别。

在这个时候,探索工作一度陷入停滞不前的状态。“山重水复疑无路,柳暗花明又一村”,在一次摸索的过程中无意中发现了recursive这个参数,这个参数可以获取当前层级及以下层级的所有数据。于是果断借助recursive参数调用 curl --digest 'http://username:password@ip:9990/management?recursive' 这个接口一次性获取全量数据,然后根据这个接口返回数据的层级关系,再逐步探索HTTP management API接口便轻松自如多了。但是这个接口有个明显的缺陷,就是:获取数据量太大、太全,导致接口返回数据比较慢,当然在这过程中,对服务器的性能损耗也是更高的。所以在获取配置的时候我们没有选择使用这个接口。

这里只介绍这3个我们目前用到的接口,我们也摸索出来了一些获取各种运行时数据的接口,有机会可以与大家详细交流,这里不再赘述。

3.3.3对比测试

切换了获取配置信息的方式后,对服务器的性能损耗已降到很低,获取配置的持续时间降到很短,为了对比两种方式的性能提升,我们采用1台2C4G的standalone的机器做了测试对比。

测试环境: 虚机配置:2C4G 整体CPU消耗:<1% WildFly实例:1 war:1 jdbc:10 jms:26

场景一: Jboss-cli方式连续(串行)10次获取全量jdbc、jms配置 执行时间:10:43:08 ~ 10:50:43 耗时:2分44秒 CPU使用:>60%

Http方式连续(串行)10次获取全量jdbc、jms配置 执行时间:10:57:37 ~ 11:00:21 耗时:7分35秒 CPU使用:<3%

image

image

场景二

Jboss-cli方式并发10次获取所有jdbc、jms配置 执行时间:14:38:31 ~ 14:44:43(最迟) 耗时:6分12秒 CPU使用:>85%

Http方式并发10次获取所有jdbc、jms配置 执行时间:14:55:06 ~ 14:55:25 耗时:19秒 CPU使用:<7%

image

image

image

通过以上对比数据可以看出,在串行模式下http方式比jboss-cli方式获取配置信息的效率提高了1.77倍,CPU资源使用降低了19倍;在并发模式下http方式比jboss-cli方式获取配置信息的效率提高了18倍,CPU资源使用降低了11倍。可见,http方式比起jboss-cli方式具有资源消耗低、效率高的特点,在jboss配置巡检上极具优势。

以上并发场景应用在我们实际环境中暂时体现不出来,我们目前是单实例的部署架构,每个实例只需要执行一次。

在实际应用中效果会更为显著,以现网5万个wildfly实例为例,粗略估算一下,按1000并发执行,需50次,使用jboss-cli方式,按平均每次耗时45s算,大概需要37分钟;使用http方式,按平均每次耗时16s算,大概只需要13分钟。

以上对于单个实例的配置获取方法采用的是串行模式,先获取到应用包的信息,再获取jdbc和jms的列表,之后再从列表中循环读取每个jdbc和jms的属性。鉴于http的高并发特点,可以对获取方法进行优化,获取到jdbc和jms列表后,采用并发模式获取每个jdbc和jms的属性,在时间上将会有更大的缩减,而对服务器资源的使用不会有明显的升高。

采用这种方式的收益,不仅仅是节省时间,之前由于jboss-cli的方式占用CPU资源较高,配置抽取的任务只能放在夜里业务低峰期的时候进行,每天只能抽取一次,配置的更新频率很低,而采用http方式以后,它占用CPU资源极低的特点,再加上执行时间短,可以大大提高抽取配置的频率,一小时一次,甚至于半个小时一次,配置库做到准实时更新!

4、助力双十一大促

配置巡检的效率提升、对业务服务器资源占用的降低,是我们保障大促能力的又一大提升。

以前我们会在大促前对中间件配置进行一次全面巡检,对不合理的配置进行集中调整,时间仓促,变更密集,存在较大的风险。这次在双十一大促前夕,我们对配置巡检方法的根本优化,将原来在大促前的巡检工作放在日常进行,将集中的配置调整放在日常完成,对配置问题做到及时发现,及时处理,消除了大促前的集中变更风险。

今年的双十一大促,中间件配置巡检之路已平,运维保障,我们整装待发!

作者简介

单隆声:苏宁易购中间件运维团队负责人,负责中间件运维团队建设及运维工具建设工作,在中间件运维工作上有丰富的经验,在中间件运维工具建设上,坚持逻辑严谨、操作简洁的设计标准,以提升运维效率、标准化能力为目标,持续推进运维自动化及标准化落地。

李照刚:苏宁易购中间件运维团队技术经理、运维开发工程师,负责中间件运维工具的设计开发工作。在python脚本开发上有丰富的经验,勇于钻研新技术,加入苏宁运维团队后,对中间件运维平台进行了较大的优化,不断完善平台功能,提升执行效率。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/suning-middle-efficiency

剖析腾讯知文,智能问答机器人路在何方?

导读:近年来,智能机器人客服已经在各行各业发挥作用,替代人类更有效率地处理繁杂的事务。

但是,不可否认的是,目前市面上大多数智能客服并不能完美满足用户的需求,如难以处理未经过训练的场景问题,无法理解复杂的人类语言结构等。在技术和商业化应用上,智能客服背后的NLP和语音技术虽然已经取得了很多进步,近年来却鲜有突破性进展,成功的商业化应用仍然屈指可数。

如今,NLP和语音技术在商业化应用上遇到了哪些瓶颈?为何迟迟没有大的进步?解决问题的关键在于哪里?或许我们可以通过智能对话机器人的典型代表——腾讯知文问答系统,发掘当前智能对话机器人破解行业应用难题的答案。

知文背后的团队

经过腾讯最近一次组织架构大调整之后,知文团队从原来的SNG事业群归入了新成立的云与智慧产业事业群(CSIG),但服务和支持的相关产品和业务不变,包括腾讯云、QQ、QQ空间等。这一团队目前的研究重心,也依然放在自然语言智能交互,围绕智能交互的内涵和外延,学术研究则包括但不限于问答、对话系统、文本摘要、知识图谱、机器阅读理解等。

作为知文团队的技术负责人,钟黎主导了知文智能问答平台、知文NLP平台以及知文内容理解产品的研发工作。在此之前,他曾负责腾讯社交网络的文本分析与语义挖掘,为众多相关产品和业务提供语义分析能力。他拥有丰富的大规模机器学习应用经验,曾经在微软、PayPal、SoftBank AI Lab、IBM Research等公司任职,并参与过机器人NAO及Pepper的原型研发、Watson智能会议助理研发等。

知文系统技术架构与四次迭代

根据钟黎的介绍,腾讯知文问答系统主要可以分为四大层次:

第一层:应用层,包括智能客服机器人、智能外呼机、投诉引导机器人、任务查询机器人等各类具体业务场景机器人。

第二层:接入层,包括公有云、私有云、私有化部署等多种接入方式。

第三层:核心问答引擎,包括信息问答、知识图谱问答、任务型问答、文档型问答以及多轮交互等技术模块。

第四层:基础能力层,包括数据能力(行业与领域数据、知识库管理、迁移学习),NLP能力(基础NLP算法组件),深度学习能力(复杂模型优化、深度学习工程化),数据分析能力(自动分析与监控、趋势分析、问题预测)等。

经过数次迭代,知文不断调整优化知文的架构,以为用户提供更好的体验。钟黎告诉AI前线,知文的发展路径整体来看是实际业务需求驱动的。最开始是缘起内部业务关于客服的工单统计和分类的需求,辅助人工客服。之后,团队发现其实可以用问答技术去解决大量频繁、重复又比较简单的问题,以减少人工客服的问询量。随着时间的推移,知文团队又遇到新的业务需求,即没有工单,而是有比较多知识和文档的场景,因此又逐渐引入知识图谱技术、机器阅读理解技术。目前,知文的研究重点,一方面是在无标注数据或者少量标注数据下,知文问答平台可以快速高效冷启动的方案,另一方面是多轮会话下解决用户意图在多个机器人间来回跳转的问题。

在规模和应用上,知文系统已经支持了5大行业的智能客服,得到20多家行业头部客户的采用,包括中国银行的新一代客服机器人项目,以及由腾讯CEO马化腾亲自站台的“一部手机游云南”项目。

经过架构的不断优化,知文核心问答机器人架构至今已经过四次迭代。钟黎介绍道,这四大核心机器人主要是指信息问答机器人、文档阅读理解机器人、任务执行机器人以及知识图谱机器人,但具体的迭代路径、方法和思考,钟黎表示将会在AICon上揭晓。

知文在NLP和语音技术上的突破

NLP和语音在技术上仍然有很多亟待解决的问题,为解决这些问题,知文问答系统做出了诸多优化和创新。例如,在核心的问答匹配上,其匹配模型引入了ELMO表示、词图卷积、intra/inter-attention机制、位序损失、GLU通路等,比当前主流的匹配模型如MatchPyramid、AICNN、BiMPM等有更好的表现。在文档阅读理解上,知文问答模型引入了template answer guiding以及tree-based spanning,突破了大部分学术论文只能做答案在原文中完全匹配且完全基于监督数据的方法。在任务型问答上,知文问答模型在end-to-end的记忆网络上进行了知识增强,对于多轮的任务型场景,模型能够有效地记忆更长的会话信息和槽位状态。

对于一家企业来说,打造一个能够满足用户大多数需求的问答机器人绝非易事,在技术和落地上均会面临很多挑战。钟黎告诉AI前线,知文团队在打造智能问答平台的过程中遇到过很多技术难点,在业务落地上也是如此。

其中,知文在业务落地中常见的难点,第一个就是业务方往往没有大量的标注数据。智能问答平台里包含了多个算法模型,如果每个都是监督模型的话,意味着在上线之前需要“喂”进去大量的监督数据,这对于业务方来说是很大的标注负担。第二个问题,就是业务方往往没有特别地进行知识库管理,大多数是一些历史工单或者FAQ问题,这些数据的结构化程度还不够高,没有形成知识图谱或者层级关系。基于这些数据做多轮和反问交互,对知文来说是一个挑战。针对这些问题,知文平台在数据标注方面采用了few-shot learning的思想,并通过迁移学习的方式,如表征迁移、模型框架迁移等,极大地降低了业务接入的数据门槛;另一方面,在无结构知识库管理上,知文平台通过自动图谱构建、动态子图生成的方式,实现通用多轮和反问的交互方式。

NLP与语音未来趋势

NLP与语音交互融合协作

腾讯知文问答系统的背后,是NLP和语音技术相结合的技术在提供支持,这呼应了业界有人提出的观点:NLP与语音交互技术已然从独立技术,走向融合协作的道路。对此,钟黎认为,NLP与语音技术本身有着紧密的联系,语音技术的很多模型也在NLP里得到了广泛应用。一个完整的自然语言交互方案,必然需要同时融合语音和NLP的技术,例如一个典型的流程,从用户语音query进来,要经过语音唤醒、ASR、NLU、QA、NLG、TTS等最后返回语音回答给用户。腾讯知文的自然语言交互方案,现在也是正在从基于文本NLP技术,到融合语音的完整自然语言交互技术。未来,一个更加自然、功能强大的智能语音交互产品,必然是充分融合了NLP与语音技术的成果。

表征与框架层迁移学习:无标注数据也是宝藏

虽然,NLP和语音技术在最近几年在技术和应用上鲜有突破,但随着更多研究人员和企业、组织进入这一领域,相信在未来,这一领域将酝酿出新一轮爆发和突破。

关于NLP技术未来发展的趋势,钟黎认为近期NLP领域值得关注的趋势是表征与框架层的迁移学习,包括之前的word2vec、glove,Al2的ELMO,OpenAI的GPT, Fast.AI的ULM,以及Google的BERT,迁移学习从底层表示的迁移、语言模型的迁移,转变到了模型框架的迁移。

这其中,他重点强调了谷歌提出的BERT模型。“通过海量无监督数据的预训练,只需要在特定任务上对最后一层进行task-specific的修改,就能取得很好的效果,目前已经在数十个任务上验证了其有效性。这对于工业应用是很大的福音,尤其对于小数据的任务,我们只需要通过小数据来fine tune最后一层,也能取得很好的效果。在NLP领域,大量的无标注数据的潜力尚待挖掘,这些迁移学习的方法在一定程度证明了无标注数据也是宝藏。非常期待在自然语言领域无监督学习、小样本学习能够取得更多突破。”

新的落地场景:多模态内容分发、普适计算下的语言交互

落地,是所有技术最终的归属,无法落地,再好的技术也无用武之地。钟黎认为,NLP其实不是新事物,在互联网的落地应用上应该算是其他AI方向的“前辈”,从门户和搜索引擎时代开始,NLP就一直是核心技术。

现在来看,NLP技术有两个新的落地场景值得重点关注:一是多模态内容分发与内容消费,包括各种信息流、资讯圈等,大量的信息处理、聚合与触达,都广泛依赖NLP技术。另一个是普适计算下的自然语言交互,包括各种云+端的设备,例如手机、车载、音箱等等。

“人机交互的革命暗潮涌动,自然语言的方式将会在越来越多的场景发挥作用。”展望未来,钟黎如此说道。

福利时间:

钟黎将会在12月份AICon大会上做精彩分享,想要跟他进一步交流的童鞋可到现场面基。

另外大会还邀请到了来自Google、微软、亚马逊、BAT、360、京东、美团、小米等40+国内外一线AI技术负责人前来分享他们的机器学习落地实践经验,除此之外,还有知识图谱、NLP、语音识别、搜索推荐、计算机视觉、AI架构等热门技术,干货满满。

目前大会8折售票倒计时2周,团购更优惠,点击这里了解更多详情。如有任何问题,可咨询票务小姐姐:18514549229[微信同号]




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/tencent-NLP-road

CodeOne主题演讲:Java,未来已来

在上一次JavaOne大会之后,首届Oracle CodeOne大会最近于美国旧金山举行。周一晚上主旨演讲的头条是“Java:未来已来(The Future of Java Is Today)”,其中包括:新的每半年发布一次的Java/JDK的发布节奏正按计划进行;Oracle和许多其他组织将继续支持Java并为之做出贡献;有几个新的OpenJDK项目在探索提高生产力的语言功能,比如,原始字符串字面量(raw String literals)、纤程(fiber)和Continuation、外部函数和数据接口。

在Java平台团队软件开发副总裁Georges Saab简短的欢迎致辞后,第一个上台演讲的是GitHub的现场维护和支持服务(Field Services)副总裁Matthew McCullough。他强调了Java平台的开源参考实现OpenJDK的重要性,并讨论了“Skara项目”,该项目是官方OpenJDK上游Mercurial存储库基于GitHub原型的镜像。

Skara项目旨在研究用于JDK源代码的源码管理和代码审查的备选项。McCullough还谈到,大多数“有重大影响力的软件”都是全球协作开发的,并鼓励观众参与开源软件项目。为更好地说明这一目标,他还简单演示了几个GitHub的新功能。

值得一提的是,Skara项目还处在早期阶段,目前是独立的,但和社区驱动的AdoptOpenJDK项目松散地保持一致。AdoptOpenJDK项目也是上游OpenJDK存储库的镜像,并提供所有最新的和未来的JDK版本的构建,目标是为Java(包括最近发布的Java 11)的长期支持(Long Term Support,简称LTS)版本提供四年的构建和最好的社区支持。为AdoptOpenJDK项目提供商业支持的有IBM、Azul Systems,LJC、微软、Ocado Technology和Packet。

Saab重回台上后,讨论了“保留Java优点”的相关话题。Java将继续免费和开源,社区致力于提供平台的完整性,并投资于开发人员生产力和兼容性。在质量和安全上也持续地进行投入,并保持开放和透明的发展。

讲到Oracle的贡献时,Saab展示了最近开源的几个之前是商业Java平台的功能:在Java 10中有应用类数据共享(Application Class Data Sharing,简称ACDS);在Java 11中有ZGC项目(用于几千兆堆的低延迟GC)、飞行记录器任务控制(用于诊断和监控)。

新的每半年一次的发布计划已经成功交付,它为Java平台提供逐步改进,并使开发人员能够更快地访问到新功能,“不再有破坏性的主要版本”(如果计划的功能错过了发布截止日期,那么就放到下一次的发布)。Saab简单提了提新的LTS版本和Oracle支持模式,关于这些,在社区内目前存在很多困惑(InfoQ最近报道了与该主题相关的“Java还是免费的”Java Champion声明)。

该主旨演讲部分的结尾,是向OpenJDK社区中很多贡献者的致谢感言,同时也提到了几个Oracle资助的Java社区支持项目,包括Java MagazineJava User GroupsJava ChampionsjDuchess项目Oracle Academy Student Outreach以及Java Community Process(简称JCP)

Building Java together

接下来演讲的是Oracle的Java平台团队首席架构师Mark Reinhold。演讲一开始,他先提醒听众,迁移到新的Java模块系统(JEP 261)是个非常大的挑战,因为需要重写大量内部组件。但是,自从Java 9中发布该功能以来,应用效果一直不错,并且开始实现了收益。Reinhold鼓励每个Java开发人员都看看这个新功能,并给大家推荐了几本入门书。

Java 9 Module books

新的模块化架构改进了平台发布节奏,并回应了Saab早先的评论,Reinhold提到了Java 10和Java 11成功地按时交付,也提到了LTS发布会带来的影响(主要是跟Oracle提供的商业支持有关,尽管其他供应商和AdoptOpenJDK计划也提供替代的构建和社区驱动以及商业支持模块)。

该部分主旨演讲的核心信息是“Java仍然免费”,OracleJDK和OpenJDK构建非常类似(尤其是首个每半年一次的LTS发布,尽管构建可能在此日期后会出现分歧,这取决于会发布什么安全性和错误补丁到上游OpenJDK存储库)。Reinhold提到了“关于新发布模型的五大误解”,其中包括错误地认为,非LTS发布是实验性的,如果维护的是不经常迁移的系统,那么可以忽略非LTS的发布。

他还讨论了用最新的Java版本测试开源项目的社区工作,提到了两个推特标签:#WorksFineOnJDK9和#WorksLikeHeavenOnJDK11。强烈建议所有在使用Java 9或更高版本的开发人员升级到最新的版本,包括所有在使用的工具和依赖项。

Top five misconceptions Java LTS

接着,Reinhold换了一个话题,开始展望未来。目前,Java 12 / JDK 12有4个与之相关的JEP(到目前为止),包括(启用命令行标志)新switch 表达式的预览和原始字符串字面量,以及“一个AArch64端口,而非两个”和默认的CDS存档。“面对编程范例、应用领域、部署风格和硬件的不断发展”,几个未来功能的重点放在了开发人员的生产力和程序性能上。

该主旨演讲的最后部分重点介绍了4个OpenJDK的新项目。

  • Amber:“调整语言仪式的大小”,包括局部变量类型推断、无需转义排序的原始字符串字面量。
  • Loom:“Continuations和纤程”,包括删除旧的“无意义”或与线程有关的不良API方法,添加纤程,即“由Java虚拟机管理的轻量级高效线程、让开发人员能够使用同样简单的抽象,但具有更好的性能和占用更小的空间”。
  • Panama:非Java外部函数和数据接口,包括从JVM(C、C++)调用本机函数和从JVM或JVM堆访问本机数据
  • Valhalla:Value 类型和专用的泛型。

Reinhold展示了一系列实时编码演示,用的是最新(未发布)Java 12 build,其中的示例可以从以上链接的各个项目网站上找到。

社区对该Java主题演讲的反应总体上是积极的,Paul Bakker表示“CodeOne!上的主旨演讲很棒,Java生态系统看起来比以往更好。”Chris Hegerty评论道:“CodeOne!上的主旨演讲很棒,尤其是Mark Reinhold讲解技术的那部分”。

阅读英文原文:The Future of Java is Today: CodeOne (née JavaOne) Keynote Highlights

感谢冬雨对本文的审校。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/codeone-java-keynote

Mango的组织重构

为了提高敏捷性,企业应将自己划分为一些负责业务战略计划价值中心,,承担端到端的责任,并完全获取有关客户需求的信息。企业需要为员工营造可交叉协作的空间,可以学习和使用自组织的改进圈、实践社群(CoP,Communities of Practice)或内部开源模型(Open Source Model)。

泽维尔·阿尔瓦拉德霍(Xavier Albaladejo)是Mango的一位敏捷和精益教练。在2018希腊敏捷峰会(Agile Summit Greece 2018)上,阿尔瓦拉德霍做演讲探讨了组织重构问题。InfoQ以简报、文章和问答方式覆盖报道了大会的全程。

在阿尔瓦拉德霍看来,企业的未来发展,应去规模化,精简为一些可称为“价值中心”的较小单元。每个单元都负责业务战略计划,承担端到端的责任,并完全获取有关客户需求的信息。战略对于企业意味着,需更更多地考虑未来数年内的发展,而不是仅仅是最近这几个月。由此,企业应为那些针对特定业务领域构建的高绩效团队营造空间。

阿尔瓦拉德霍指出,一旦企业的结构直接映射为企业的战略,就可为企业的员工提供明确的目标,并赋予员工自治权。对于承担了企业中部分单元的员工,目标应是做到从“授权”理念转变为“自主权”,使员工可以自身营造成功所需的环境。

作为《去规模化:人工智能和新一代企业如何创造未来经济》(“Unscaled:How AI and a New Generation of Upstarts Are Creating the Economy of the Future”)一书的作者,Hemant Taneja在近期InfoQ对该书作者的问答中,解释了企业应如何做到去规模化:

Taneja 去规模化现象事实上应一分为二地看待。一部分是企业租用服务而非自建服务的能力,其中涉及从办公环境到支付平台的各个环节。另一部分是日益复杂的人工智能技术和数据访问方式对创新的步伐和特异度(specificity)的影响,这是我们看到正在逐渐浮现的一个现象。那些处于早期发展中的企业可更多地从中受益,更快地迭代发展,进而针对更适合的、更小规模的市场推出更好的产品和解决方案。

阿尔瓦拉德霍也指出了企业在建立较小单元中存在的一个缺点,即在破坏功能筒仓的同时,在设计上又给出了这些称之为“价值中心”的新筒仓。更糟糕的是,由于相比起以往任何时候而言,这些承担了各“价值中心”的员工对自身的业务目标具有更清晰的认识,所以他们在默认情况下并没有开展交叉合作的动力。除非企业投入时间找到非常优秀的天生领导者,由他为员工营造一个空间,大家愿意相互分享并充分利用在同一家公司下的优势。

阿尔瓦拉德霍提出,在大型系统中,人们除非一起共事,否则并不会产生归属感。Mango的做法是投入时间激发员工参与战略和改进环(即业务、技术和组织)、参与实践社群以分享经验和所学、转向内部开源模型等。

InfoQ就Mango的组织重构情况采访了阿尔瓦拉德霍。

InfoQ:为什么需要对Mango做重构?

泽维尔·阿尔瓦拉德霍: 通常,那些创立于二三十年前的企业,甚至是一些新企业,都采用了基于专业分工的内部结构,例如营销部门、销售部门、技术部门、客户服务部门、人力资源部门等。由此,人们无法通过这样企业的组织结构图了解该企业的具体业务。从企业结构设计上看,这种结构类型创立了部门级筒仓,每个筒仓有自己的做事优先级、自己的预算,因此它们毫无动力去开展交叉协作。部门间对产出不存在共同责任,对需求、关键价值点等客户相关信息也不存在共同视角。

企业内部,各部门间的工作堆积如山,破坏了企业的价值链,并导致企业对市场需反应异常缓慢。当前,由于客户行为方式发生了改变,这种做法已变得不可持续。尽管企业自然会向数字化转型,但人们已经习惯于他们的问题几乎立刻就能得到解决。企业将被迫与那些更“小型化”并更“敏捷”的企业竞争,而后者会提供更简单的解决方案,其中不再存在传统的结构、流程、技术和文化。鉴于当前一些大型企业的利润率不高于10%(参见近年来股票市场的表现),一旦企业开始失去客户,这就意味着整个企业已经踏在了悬崖边上。

上面提及的存在于Mango中的一些预期“系统行为”,也同样存在于任何一家具有这种规模和内部结构的企业。因此,企业有需求去创建一些内部的“衍生产品”。以创立于十多年前的Mango线上部门为例,尽管它符合相对于企业其它部门尽可能自治的理念,但其内部结构仍然是基于专业分工的。当前,该部门正在推进各种“价值中心”的转型,并获得了来自企业中其它部门的牵引力,以扩大端到端的价值链视角。这种转变是十分自然发生的,因为市场要求越来越多的在线销售和全渠道服务。

InfoQ:您是如何在Mango建立网络式组织的?

阿尔瓦拉德霍: 关键之一在于使任何改进措施都具有包容性,邀请员工参与其中,并适应那些在他们看来可为企业其它部门带来更多价值之处。如上所述,我们定期举办开放式研讨会,讨论每项专业战略和改进。这也为大家分享所学知识和小组工作事宜提供了空间。只有多次探索,才能找出使员工感到有价值和愉快的最有效方法。使工作更社交化、更有趣甚至是“令人惊喜”,这也是同等重要的。要让员工下班回家后笑着告诉家人或朋友,“大家必须听一听我今天在工作中做的事情!”。

InfoQ:这种做法是如何影响领导力的?

阿尔瓦拉德霍: 为实现“价值中心”周边环境尽可能无缝的融合,需要这些“价值中心”承担责任并具备自主权,此外还需要做大量的工作。首要的影响是,作为教练,必须去教授管理层,让他们学习并练习大量新的心理模型。其次,作为这种做法的结果,我们需要具备能制定战略并发挥其作用的真正领导者,将员工整合在一起投入到工作中。这样方式下企业才会达成其主要目标之一,即利用好公司全体员工的群策群力。第三,企业在这种新结构下将变得更为扁平化。企业需要重构部分管理层,让他们转向到一些承担新角色的团队内部工作,或者让他们“半兼职”地担当技能或专业辅导员,这些辅导员需要与一些特定的团队肩并肩地合作数周。

InfoQ:Mango在敏捷转型中,有哪些经验教训?

阿尔瓦拉德霍: 重点是要解释清楚,你的目的并非是要在企业中引入敏捷,而是要去解决大家面对的问题,实现大家的愿景。敏捷、精益、Scrum和看板等,都只是一些手段,而并非做事的目的。要想取得成功,你的沟通风格应该保持与企业高层的管理风格完全契合,并且非常有必要对高层管理价值和技能自底向下地开展全球范围的调查,让高层管理者清晰地了解在哪些问题上应该做出改进。另一个关键问题是,高层管理者应该保持谦虚,不要害怕对企业中事务做出改进。而企业的中层管理人员应该真正地保持一种开放的心态,渴望学习,否则他们可能会阻碍企业的转型。最后一点,真正能使企业产生改变的做法在于,企业管理层是否能够以协作的方式让企业的员工参与进来,倾听员工的意见,激励他们的工作,并顾及他们的想法。仅有好的想法是不够的,领导力决定一切。

查看英文原文: Organizational Refactoring at Mang

感谢冬雨对本文的审校。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/organizational-refactoring-mango

微软正式发布Azure IoT Central

微软正式发布Azure IoT Central,这是一个面向物联网的软件即服务解决方案。借助该服务,微软旨在提供一种设计、开发、配置和管理IoT设备的低代码方式,同时提供开箱即用的安全性、可伸缩性以及与流程&应用程序集成。

Azure IoT Central构建于Azure IoT Hub之上,后者是微软的一个服务解决方案,用于在IoT设备和云解决方案之间创建可靠、安全的双向通信,很像Google Cloud IoTAWS IoT。不过,Azure IoT Central并不是仅仅提供构建和管理整个物联网平台的工具,而是让任何人都可以使用它,即使没有云方面的专业知识,正如Digital Trends工作人员Arif Bacchus所说的那样。

基于Azure云的强大功能,它为客户和合作伙伴提供了完全托管的SaaS,可以实现功能强大的物联网场景,而不需要云解决方案的专业知识。

客户可以想象下Azure IoT Central提供的大量功能,从快速安装新设备以获得见解到解释它们的数据,而不需要很了解IoT解决方案。例如,现在可以使用“设备配置服务(Device Provisioning Service)”利用“自动服务配置(zero-touch provisioning)”连接新设备。此外,作业提供了批量设备管理功能,可以重新引导、重置或更新设备。此外,这些都是在物联网场景中预期的规模上完成的,并且可以针对特定的设备或设备组。Azure IoT Central还提供了设备模板的概念,用于重用现有的配置。

设备模板是一个模型,定义了连接到Azure IoT Central应用程序的设备类型的特征和行为。

当涉及到监控设备时,监控规则允许自动触发最多5个动作,可以通知人或其他系统。然后,这些动作可以调用各种各样的服务,比如发送电子邮件、利用Azure Functions执行定制代码或调用其他服务的webhook。另一种可能是通过集成Microsoft Flow实现工作流,提供对Azure内外许多服务连接器的访问。此外,在正式宣布Azure IoT Central的同时,微软还宣布并入Connected Field Service,使用户可以利用设备数据主动进行定期维护。

图片来源: https://docs.microsoft.com/en-us/azure/iot-central/concepts-architecture

物联网场景另外一个重要的方面是深入了解从各种设备接收到的数据。因此,Azure IoT Central提供了开箱即用的分析,它允许用户以最少的配置更好地理解数据。此外,微软还提供了PowerBI解决方案,直接处理来自Azure IoT Central的数据,并提供额外的功能来分析IoT解决方案的指标。

  1. 跟踪设备在一段时间内发送了多少数据
  2. 比较遥测、状态和事件之间的数据量
  3. 识别报告大量测量数据的设备
  4. 观察设备测量的历史趋势
  5. 识别发送大量关键事件的有问题的设备

最后,在发布正式公告的同时,微软还调整了Azure IoT Central的价格。现在,它允许免费使用少量设备,同时提供一个向下倾斜的定价模型。

查看英文原文:Microsoft Announces General Availability of Azure IoT Central




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/microsoft-azure-iot-central

CyberMiles为Google私用网络提供区块链支持

为什么 Google 要构建私用网络?

互联网是巨大的,但它是成千上万个小型私用网络的大杂烩,通过数千个互联网服务提供商(ISP)和数十个大型运营商和服务提供商运营的骨干网连接起来。

将数据从互联网的一端移动到另一端,可能意味着要在许多不同的计算机和不同的网络之间移动。在这些计算机和网络中,有一些是老旧的、低效的;而有一些是现代的、高效的。它们都是通过一系列的标准联系在一起,形成了我们所说的互联网。这些标准决定了数据包如何完整无损地到达目的地。

许多大型互联网公司通过建立自己的数据中心、网络、骨干网等,拥有大量的互联网。这有助于降低成本。

Google 就是那些拥有大量互联网的公司之一。它在全球拥有 50 多个数据中心,构建自己的服务器,运行自己的骨干网,将大量数据传送到世界各地,开发了自己的软件来管理所有的数据,将大量的服务器组保存在 ISP 的数据中心内,这样就可以将数据缓存到更接近交付的位置……

Google 到底有多大?Arbor 说:

Google 真的很大。如果 Google 是一家互联网服务提供商的话,那么它将是增长最快的第三大全球运营商。只有另外两个提供商(两者都携带大量的 Google 传输)提供更多的域间流量。但与大多数全球运营商(即 “tier1”)不同的是,Google 的骨干网并不代表数百万用户或数千个区域网络和大型企业提供流量。Google 的基础设施只支持 Google 自家。

Google、Microsoft、Yahoo 和其他大型内容提供商之间的竞争早已超越了谁拥有更好的视频或搜索的阶段。如今,争夺互联网主导地位的竞争同样与基础设施有关:原始数据中心的计算能力,以及向消费者教辅内容的效率(即快速和廉价)。

这就是为什么 Google 一直致力于构建最高效、成本最低的私用互联网。这种基础设施是 Google 的关键,也是理解 Google 的关键。

此外,Google 还是最早意识到电力成本是决定数据中心成本方面非常重要的公司之一。Google 的主要目标是使用可再生能源发电,成本低于煤炭发电。那将是一个令人难以置信的成就。

Google 是时候为区块链优化私用网络了

Google 创建了自己的互联网,是用自己的云平台搭建的全球私用网络。现在 CyberMiles 正在帮助这个网络为区块链提供支持。

这家搜索巨头是加密项目的重要投资者,现在它会不会更加紧密地支持这些项目呢?

如果你问你的奶奶,她是如何上网的,这里的 “上网” 不是指如何连接路由器什么的,她有可能会跟你说她是通过 Google 来上网的。虽然这个回答很可爱,但从某种意义来说,她也没有说错。因为这几年来,这个无处不在的搜索巨头和互联网的界限日趋重叠了,尤其是 Google 占到了互联网流量的 25%。

Google 也在建立自己的私用互联网。早在 2005 年,Google 就购买了遍布世界各地埋在地下的数千英里未使用的光缆,现在,它拥有超过 100 个网络接入点和超过 7500 个全球云网络用户入口点。Google 甚至在今年还增加了三条新的海底电缆,还自豪地宣称:“我们还没完成这一工程。”

但是 Google,作为 2012~2017 年区块链公司的第二大投资者,并没有为区块链优化自己的全球私用网络。CyberMiles 希望改变这一状况。

电子商务区块链平台周二宣布与 Google 合作。CyberMiles 打算改变 Google 的基础设施的设置,以改善区块链公司的产品。这将涉及网络如何通信以及如何支持防火墙的更改。两家公司都计划进行联合案例研究,来展示这些改进。CyberMiles 于 10 月 15 日宣布推出自家的主网,在开发测试网和主网时也使用了 Google 云服务。

据区块链公司首席科学家 Michael Yuan 的说法,CyberMiles 最初接触 Google 的初衷是为了在其全球私用网络能够支持他们的平台。Google 网络可以让数据在任何数据中心之间传输,而无需离开自己的更为快速的光缆。这一点引起了 CyberMiles 的兴趣,因为截至本文撰写时,这个平台只有有限数量的节点支持 blockchain-35,这些节点之间的通信对其运行能力至关重要。

尽管私用网络的好处显而易见,但它也提出了一些问题。也就是说,它是否足够去中心化?安全性如何?Yuan 表示,由于这些因素,他们一直与 Google 进行合作,以确保在网络上能够进行更有效的通信,并确保灵活的防火墙配置。后者非常重要,因为 CyberMiles 的网络节点需要受到防火墙的严密保护,并且需要灵活性来防止骇客入侵。

目前,Google 正在采取措施进入中国,这将让 Google 面对中国广泛的互联网内容审查。在全球范围内,它也在创建这种私用互联网,最终有望被企业和个人广泛使用。这些会不会是互联网更加集中化的开端呢?区块链用户会不会直接与他们合作,引导他们决定重大决策来走向更加去中心化的方向呢?Web 3.0 还在各方激烈博弈中。

感谢杜小芳对本文的审校。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/10/CyberMiles-chainblock-for-Google

写给服务器端Java开发人员的Kotlin简介

本文要点

  • Kotlin为JVM平台带来了编译时空检查、功能切面和富有表达力的语法
  • Kotlin可以与Java互操作,可以逐步引入到现有的Java项目中
  • 对于拥有大量样板文件和逻辑的项目,Kotlin是一个不错的选择
  • Kotlin很好地集成了流行的框架,包括Spring和Hibernate
  • Kotlin可以通过消除样板文件来显著减少Java代码库的大小

Kotlin简介

Kotlin是JVM上比较新的语言之一,来自IntelliJ开发商JetBrains。它是一种静态类型语言,旨在提供一种混合OO和FP的编程风格。Kotlin编译器生成的字节码与JVM兼容,可以在JVM上运行及与现有的库互操作。2017年,谷歌支持将其用于Android开发,Kotlin获得了重大突破。

JetBrains有一个明确的目标:让Kotlin成为一种多平台语言,并提供100%的Java互操作性。Kotlin最近的成功和成熟水平为它进入服务器端提供了一个很好的机会。

选择Kotlin的理由

许多语言都试图成为更好的Java。Kotlin在语言和生态系统方面做得都很好。成为更好的Java,同时又要保护JVM和巨大的库空间,这是一场姗姗来迟的进化。这种方法与来自JetBrains和谷歌的支持相结合,使它成为一个真正的竞争者。让我们来看看Kotlin带来的一些特性。

类型推断 —— 类型推断是一等特性。Kotlin推断变量的类型,而不需要显式指定。在需要明确类型的情况下,也可以指定类型。

通过引入var关键字,Java 10也在朝着类似的方向发展。虽然表面看起来类似,但它的范围仅限于局部变量,不能用于字段和方法签名。

严格空检查 —— Kotlin将可空代码流视为编译时错误。它提供了额外的语法来处理空检查。值得注意的是,它提供了链式调用中的NPE保护。

与Java互操作 —— Kotlin在这方面明显优于其他JVM语言。它可以与Java无缝地交互。可以在Kotlin中导入框架中的Java类并使用,反之亦然。值得注意的是,Kotlin集合可以与Java集合互操作。

不变性 —— Kotlin鼓励使用不可变的数据结构。常用的数据结构(Set/ List/ Map)是不可变的,除非显式地声明为可变的。变量也被指定为不可变(val)和可变(var)。所有这些变化对状态可管理性的影响是显而易见的。

简洁而富有表达力的语法 —— Kotlin引入了许多改进,这些改进对代码的可读性产生了重大影响。举几个例子:

  • 分号是可选的
  • 大括号在没有用处的情况下是可选的
  • Getter/Setter是可选的
  • 一切都是对象——如果需要,在后台自动使用原语
  • 表达式:表达式求值时返回结果

在Kotlin中,所有的函数都是表达式,因为它们至少返回Unit 。控制流语句如iftrywhen(类似于switch)也是表达式。例如:

String result = null;

try {
    result = callFn();
} catch (Exception ex) {
    result = “”;
}

becomes:

val result = try {
    callFn()
} catch (ex: Exception) {
    “”
}

循环支持范围,例如:

for (i in 1..100) { println(i) }

还有一些其他的改进,我们将继续讨论。  

把Kotlin引入Java项目

循序渐进

考虑到Java的互操作性,建议循序渐进地将Kotlin添加到现有的Java项目中。主流产品的支持项目通常是不错的选择。一旦团队感到舒适了,他们就可以评估自己是否更喜欢完全切换。

选择哪类项目好?

所有的Java项目都可以从Kotlin中获益。但是,具有以下特征的项目可以使决策更简单。

包含大量DTO或模型/实体对象的项目 —— 这对于处理CRUD或数据转换的项目非常典型。此类项目往往充斥着getter/setter。这里可以利用Kotlin的属性大幅简化类。

大量依赖实用工具类的项目 —— Java中的实用工具类通常是为了弥补Java中顶级函数的缺乏。在许多情况下,这包括含全局无状态public static函数。这些可以分解成纯函数。更进一步,Kotlin支持类似Function类型这样的FP结构和高阶函数,这可以用来使代码更易于维护和测试。

类中逻辑复杂的项目 —— 这些项目容易受到空指针异常(NPE)的影响,而这是Kotlin很好地解决了的其中一个问题。通过让语言分析可能导致NPE的代码路径为开发人员提供支持。Kotlin的when结构(一个更好的switch)在这里非常有用,可以将嵌套的逻辑树分解为可管理的函数。对变量和集合的不变性支持有助于简化逻辑,避免由于引用泄漏而导致难以查找的错误。虽然上面的一些功能可以通过Java实现,但Kotlin的优势在于升级了这些范例,并使它们保持简洁一致。

让我们在这里暂停一下,看一个典型的Java逻辑片段以及对应的Kotlin实现:

public class Sample {
  
   public String logic(String paramA, String paramB) {
       String result = null;
       try {
           if (paramA.length() > 10) {
               throw new InvalidArgumentException(new String[]{"Unknown"});
           } else if ("AB".equals(paramA) && paramB == null) {
               result = subLogicA(paramA + "A", "DEFAULT");
           } else if ("XX".equals(paramA) && "YY".equals(paramB)) {
               result = subLogicA(paramA + "X", paramB + "Y");
           } else if (paramB != null) {
               result = subLogicA(paramA, paramB);
           } else {
               result = subLogicA(paramA, "DEFAULT");
           }
       } catch (Exception ex) {
           result = ex.getMessage();
       }
       return result;
   }
   private String subLogicA(String paramA, String paramB) {
       return paramA + "|" + paramB;
   }
}

对应的Kotlin实现:

fun logic(paramA: String, paramB: String?): String {
   return try {
       when {
           (paramA.length > 10) -> throw InvalidArgumentException(arrayOf("Unknown"))
           (paramA == "AB" && paramB == null) -> subLogicA(paramA + "A")
           (paramA == "XX" && paramB == "YY") -> subLogicA(paramA + "X", paramB + "X")
           else -> if (paramB != null) subLogicA(paramA, paramB) else subLogicA(paramA)
       }
   } catch (ex: Exception) {
       ex.message ?: "UNKNOWN"
   }
}
private fun subLogicA(paramA: String, paramB: String = "DEFAULT"): String {
   return "$paramA|$paramB"
}

虽然这些代码片段在功能上是等效的,但是它们有一些明显的区别。

logic()函数不需要包含在类中。Kotlin提供了顶级函数。这开辟了一个广阔的空间,鼓励我们去思考是否真的需要一个对象。单独的纯函数更容易测试。这为团队提供了采用更简洁的函数方法的选项。

Kotlin引入了when,这是一个处理条件流的强大结构。它比ifswitch语句的功能要强大得多。任意逻辑都可以使用when进行条理的组织。

注意,在Kotlin版本中,我们从未声明返回变量。这是可能的,因为Kotlin允许我们使用whentry作为表达式。

subLogicA函数中,我们可以在函数声明中为paramB指定一个默认值。

private fun subLogicA(paramA: String, paramB: String = "DEFAULT"): String {

现在,我们可调用任何一个函数签名了:

subLogicA(paramA, paramB)

或者

subLogicA(paramA) # In this case the paramB used the default value in the function declaration

现在,逻辑更容易理解了,代码行数减少了约35%。

把Kotlin加入Java构建

MavenGradle通过插件支持Kotlin。Kotlin代码被编译成Java类并包含在构建过程中。Kobalt等比较新的构建工具看起来也很有前景。Kobalt受Maven/Gradle启发,但完全是用Kotlin编写的。

首先,将Kotlin插件依赖项添加到MavenGradle构建文件中。

如果你使用的是Spring和JPA,你还应该添加kotlin-springkotlin-jpa编译器插件。项目的编译和构建没有任何明显的差异。

如果要为Kotlin代码库生成JavaDoc则需要这个插件

有针对IntelliJ和Eclipse Studio的IDE插件,但正如我们所预料的那样,Kotlin的开发和构建工具从IntelliJ关联中获益良多。从社区版开始,该IDE对Kotlin提供了一等支持。其中一个值得注意的特性是,它支持将现有的Java代码自动转换为Kotlin。这种转换很准确,而且是一种很好的学习Kotlin惯用法的工具。

与流行框架集成

因为我们将Kotlin引入了现有的项目中,所以框架兼容性是一个问题。Kotlin完美融入了Java生态系统,因为它可以编译成Java字节码。一些流行的框架已经宣布支持Kotlin,包括Spring、Vert.x、Spark等。让我们看下Kotlin和Spring及Hibernate一起使用是什么样子。

Spring

Spring是Kotlin的早期支持者之一,在2016年首次增加支持。Spring 5利用Kotlin提供更简洁的DSL。你可以认为,现有的Java Spring代码无需任何更改就可继续运行。

Kotlin中的Spring注解

Spring注释和AOP都是开箱即用的。你可以像注解Java一样注解Kotlin类。考虑下面的服务声明片段。

@Service
@CacheConfig(cacheNames = [TOKEN_CACHE_NAME], cacheResolver = "envCacheResolver")
open class TokenCache @Autowired constructor(private val repo: TokenRepository) {

这些是标准的Spring注解:

@Service: org.springframework.stereotype.Service

@CacheConfig: org.springframework.cache

注意,constructor是类声明的一部分。

@Autowired constructor(private val tokenRepo: TokenRepository)

Kotlin将其作为主构造函数,它可以是类声明的一部分。在这个实例中,tokenRepo是一个内联声明的属性。

编译时常量可以在注解中使用,通常,这有助于避免拼写错误。

final类处理

Kotlin类默认为final的。它提倡将继承作为一种有意识的设计选择。这在Spring AOP中是行不通的,但也不难弥补。我们需要将相关类标记为open —— Kotlin的非final关键字。

IntelliJ会给你一个友好的警告。

你可以通过使用maven插件all open来解决这个问题。这个插件可以open带有特定注解的类。更简单的方法是将类标记为open

自动装配和空值检查

Kotlin严格执行null检查。它要求初始化所有标记为不可空的属性。它们可以在声明时或构造函数中初始化。这与依赖注入相反——依赖注入在运行时填充属性。

lateinit修饰符允许你指定属性将在使用之前被初始化。在下面的代码片段中,Kotlin相信config对象将在首次使用之前被初始化。

@Component
class MyService {

   @Autowired
   lateinit var config: SessionConfig
}

虽然lateinit对于自动装配很有用,但我建议谨慎地使用它。另一方面,它会关闭属性上的编译时空检查。如果在第一次使用时是null仍然会出现运行时错误,但是会丢失很多编译时空检查。

构造函数注入可以作为一种替代方法。这与Spring DI可以很好地配合,并消除了许多混乱。例如:

@Component
class MyService constructor(val config: SessionConfig)

这是Kotlin引导你遵循最佳实践的一个很好的例子。

Hibernate

Hibernate和Kotlin可以很好地搭配使用,不需要做大的修改。一个典型的实体类如下所示:

@Entity
@Table(name = "device_model")
class Device {

   @Id
   @Column(name = "deviceId")
   var deviceId: String? = null

   @Column(unique = true)
   @Type(type = "encryptedString")
   var modelNumber = "AC-100"

   override fun toString(): String = "Device(id=$id, channelId=$modelNumber)"

   override fun equals(other: Any?) =
       other is Device
           && other.deviceId?.length == this.deviceId?.length
           && other.modelNumber == this.modelNumber

   override fun hashCode(): Int {
       var result = deviceId?.hashCode() ?: 0
       result = 31 * result + modelNumber.hashCode()
       return result
   }
}

在上面的代码片段中,我们利用了几个Kotlin特性:

属性

通过使用属性语法,我们就不必显式地定义gettersetter了。这减少了混乱,使我们能够专注于数据模型。

类型推断

在我们可以提供初始值的情况下,我们可以跳过类型规范,因为它可以被推断出来。例如:

var modelNumber = "AC-100"

modelNumber属性会被推断为String类型。

表达式

如果我们稍微仔细地看下toString()方法,就会发现它有与Java有一些不同:

override fun toString(): String = "Device(id=$id, channelId=$modelNumber)"

它没有返回语句。这里,我们使用了Kotlin表达式。对于返回单个表达式的函数,我们可以省略花括号,通过等号赋值。

字符串模板

"Device(id=$id, channelId=$modelNumber)"

在这里,我们可以更自然地使用模板。Kotlin允许在任何字符串中嵌入${表达式}。这消除了笨拙的连接或对String.format等外部辅助程序的依赖。

相等测试

equals方法中,你可能已经注意到了这个表达式:

other.deviceId?.length == this.deviceId?.length

它用==符号比较两个字符串。在Java中,这是一个长期存在的问题,它将字符串视为相等测试的特殊情况。Kotlin最终修复了这个问题,始终把==用于结构相等测试(Java中的equals())。把===用于引用相等检查。

数据类

Kotlin还提供一种特殊类型的类,称为数据类。当类的主要目的是保存数据时,这些类就特别适合。数据类会自动生成equals()hashCode()toString()方法,进一步减少了样板文件。

有了数据类,我们的最后一个示例就可以改成:

@Entity
@Table(name = "device_model")
data class Device2(
   @Id
   @Column(name = "deviceId")
   var deviceId: String? = null,

   @Column(unique = true)
   @Type(type = "encryptedString")
   var modelNumber: String = "AC-100"
)

这两个属性都作为构造函数的参数传入。equalshashCodetoString是由数据类提供的。

但是,数据类不提供默认构造函数。这是对于Hibernate而言是个问题,它使用默认构造函数来创建实体对象。这里,我们可以利用kotlin-jpa插件,它为JPA实体类生成额外的零参数构造函数。

在JVM语言领域,Kotlin的与众不同之处在于,它不仅关注工程的优雅性,而且解决了现实世界中的问题。

采用Kotlin的实际好处

减少空指针异常

解决Java中的NPE是Kotlin的主要目标之一。将Kotlin引入项目时,显式空检查是最明显的变化。

Kotlin通过引入一些新的操作符解决了空值安全问题。Kotlin的?操作符就提供了空安全调用,例如:

val model: Model? = car?.model

只有当car对象不为空时,才会读取model属性。如果car为空,model计算为空。注意model的类型是Model?——表示结果可以为空。此时,流分析就开始起作用了,我们可以在任何使用model 变量的代码中进行NPE编译时检查。

这也可以用于链式调用:

val year = car?.model?.year

下面是等价的Java代码:

Integer year = null;
if (car != null && car.model != null) {
   year = car.model.year;
}

一个大型的代码库会省掉许多这样的null检查。编译时安全自动地完成这些检查可以节省大量的开发时间。

在表达式求值为空的情况下,可以使用Elvis操作符( ?: )提供默认值:

val year = car?.model?.year ?: 1990

在上面的代码片段中,如果year最终为null,则使用值1990。如果左边的表达式为空,则?: 操作符取右边的值。

函数式编程选项

Kotlin以Java 8的功能为基础构建,并提供了一等函数。一等函数可以存储在变量/数据结构中并传递出去。例如,在Java中,我们可以返回函数:

@FunctionalInterface
interface CalcStrategy {
   Double calc(Double principal);
}

class StrategyFactory {
   public static CalcStrategy getStrategy(Double taxRate) {
       return (principal) -> (taxRate / 100) * principal;
   }
}

Kotlin让这个过程变得更加自然,让我们可以清晰地表达意图:

// Function as a type
typealias CalcStrategy = (principal: Double) -> Double
fun getStrategy(taxRate: Double): CalcStrategy = { principal -> (taxRate / 100) * principal }

当我们深入使用函数时,事情就会发生变化。下面的Kotlin代码片段定义了一个生成另一个函数的函数:

val fn1 = { principal: Double ->
   { taxRate: Double -> (taxRate / 100) * principal }
} 

我们很容易调用fn1及结果函数:

fn1(1000.0) (2.5)

输出
25.0

虽然以上功能在Java中也可以实现,但并不直接,并且包含样板代码。

提供这些功能是为了鼓励团队尝试FP概念,开发出更符合要求的代码,从而得到更稳定的产品。

注意,Kotlin和Java的lambda语法略有不同。这在早期可能会给开发人员带来烦恼。

Java代码:

( Integer first, Integer second ) -> first * second

等价的Kotlin代码:

{ first: Int, second: Int -> first * second }

随着时间的推移,情况就变得明显了,Kotlin支持的应用场景需要修改后的语法。

减少项目占用空间大小

Kotlin最被低估的优点之一是它可以减少项目中的文件数量。Kotlin文件可以包含多个/混合类声明、函数和枚举类等其他结构。这提供了许多Java没有提供的可能性。另一方面,它提供了一种新的选择——组织类和函数的正确方法是什么?

在《代码整洁之道》一书中,Robert C Martin打了报纸的比方。好代码应该读起来和报纸一样——高级结构在文件上部,越往下面越详细。这个文件应该讲述一个紧凑的故事。Kotlin的代码布局从这个比喻中可见一斑。

建议是——把相似的东西放在一起——放在更大的上下文里。

虽然Kotlin不会阻止你放弃“结构(structure)”,但这样做会使后续的代码导航变得困难。组织东西要以它们之间的关系和使用顺序为依据,例如:

enum class Topic {
    AUTHORIZE_REQUEST,
    CANCEL_REQUEST,
    DEREG_REQUEST,
    CACHE_ENTRY_EXPIRED
}

enum class AuthTopicAttribute {APP_ID, DEVICE_ID}
enum class ExpiryTopicAttribute {APP_ID, REQ_ID}

typealias onPublish = (data: Map<String, String?>) -> Unit

interface IPubSub {
    fun publish(topic: Topic, data: Map<String, String?>)
    fun addSubscriber(topic: Topic, onPublish: onPublish): Long
    fun unSubscribe(topic: Topic, subscriberId: Long)
}
class RedisPubSub constructor(internal val redis: RedissonClient): IPubSub {
...}

在实践中,通过减少为获得全貌而需要跳转的文件数量,可以显著减少脑力开销。

一个常见的例子是Spring JPA库,它使包变得混乱。可以把它们重新组织到同一个文件中:

@Repository
@Transactional
interface DeviceRepository : CrudRepository<DeviceModel, String> {
    fun findFirstByDeviceId(deviceId: String): DeviceModel?
}

@Repository
@Transactional
interface MachineRepository : CrudRepository<MachineModel, String> {
    fun findFirstByMachinePK(pk: MachinePKModel): MachineModel?
}
@Repository
@Transactional
interface UserRepository : CrudRepository<UserModel, String> {
    fun findFirstByUserPK(pk: UserPKModel): UserModel?
}

上述内容的最终结果是代码行数(LOC)显著减少。这直接影响了交付速度和可维护性。

我们统计了Java项目中移植到Kotlin的文件数量和代码行数。这是一个典型的REST服务,包含数据模型、一些逻辑和缓存。在Kotlin版本中,LOC减少了大约50%。开发人员在跨文件浏览和编写样板代码上消耗的时间明显减少。

简洁而富有表达力的代码

编写简洁的代码是一个宽泛的话题,这取决于语言、设计和技术的结合。然而,Kotlin提供了一个良好的工具集,为团队的成功奠定了基础。下面是一些例子。

类型推断

类型推断最终会减少代码中的噪音。这有助于开发人员关注代码的目标。

类型推断可能会增加我们跟踪正在处理的对象的难度,这是一种常见的担忧。从实际经验来看,这种担忧只在少数情况下有必要,通常少于5%。在大多数情况下,类型是显而易见的。

下面的例子:

LocalDate date = LocalDate.now();
String text = "Banner";

变成了:

val date = LocalDate.now()
val text = "Banner"

在Kotlin中,也可以指定类型:

val date: LocalDate = LocalDate.now()
val text: String = "Banner"

值得注意的是,Kotlin提供了一个全面的解决方案。例如,在Kotlin中,我们可以将函数类型定义为:

val sq = { num: Int -> num * num }

另一方面,Java 10通过检查右边表达式的类型推断类型。这引入了一些限制。如果我们尝试在Java中执行上述操作,我们会得到一个错误:

类型别名

这是Kotlin中一个方便的特性,它允许我们为现有类型分配别名。它不引入新类型,但允许我们使用替代名称引用现有类型,例如:

typealias SerialNumber = String

SerialNumber现在是String类型的别名,可以与String类型互换使用,例如:

val serial: SerialNumber = "FC-100-AC"

和下面的代码等价:

val serial: String = "FC-100-AC"

很多时候,typealias可以作为一个“解释变量”,提高清晰度。考虑以下声明:

val myMap: Map<String, String> = HashMap()

我们知道myMap包含字符串,但我们不知道这些字符串表示什么。我们可以通过引入String类型的别名来澄清这段代码:

typealias ProductId = String
typealias SerialNumber = String

现在,上述myMap的声明可以改成:

val myMap: Map<ProductId, SerialNumber> = HashMap()

上面两个myMap的定义是等价的,但是对于后者,我们可以很容易地判断Map的内容。

Kotlin编译器用底层类型替换了类型别名。因此,myMap的运行时行为不受影响,例如:

myMap.put(“MyKey”, “MyValue”)

这种钙化的累积效应是减少了难以捉摸的Bug。在大型分布式团队中,错误通常是由于未能沟通意图造成的。

早期应用

早期获得吸引力通常是引入变革的最困难的部分。从确定合适的实验项目开始。通常,有一些早期的采用者愿意尝试并编写最初的Kotlin代码。在接下来的几周里,更大的团队将有机会查看这些代码。人们早期的反应是避免新的和不熟悉的东西。变革需要一些时间来审视。通过提供阅读资源和技术讲座来帮助评估。在最初的几周结束时,更多的人可以决定在多大程度上采用。

对于熟悉Java的开发人员来说,学习曲线很短。以我的经验来看,大多数Java开发人员在一周内都能高效地使用Kotlin。初级开发人员可以在没有经过特殊培训的情况下使用它。以前接触过不同语言或熟悉FP概念会进一步减少采用时间。

未来趋势

从1.1版本开始,“协同例程(Co-routine)”就可以用在Kotlin中了。在概念上,它们类似于JavaScript中的async/await。它们允许我们在不阻塞线程的情况下挂起流,从而降低异步编程中的复杂性。

到目前为止,它们还被标记为实验性的。协同例程将在1.3版本中从实验状态毕业。这带来了更多令人兴奋的机会。

Kotlin的路线图在Kotlin Evolution and Enhancement Process(KEEP)的指导下制定。请密切关注这方面的讨论和即将发布的特性。

作者简介

Baljeet Sandhu是一名技术负责人,拥有丰富的经验,能够为从制造到金融的各个领域提供软件。他对代码整洁、安全和可扩展的分布式系统感兴趣。Baljeet目前为HYPR工作,致力于构建非集中式的认证解决方案,以消除欺诈,提高用户体验,实现真正的无密码安全。

查看英文原文:An Introduction to Kotlin for Serverside Java Developers




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/intro-kotlin-java-developers

为新世纪做准备——敏捷转型的五大事项

本文要点

  • 成功的转型需要强大的领导力来支持和保护敏捷文化
  • 帮助团队和利益干系人实现自组织
  • 借助结果(而不是输出)来管理项目集合
  • 系统性消除敏捷团队面临的浪费和延迟源
  • 通过频繁反馈(检查和调整)度量和改进交付的价值

敏捷转型很困难,但有必要

随着我们进入数字化时代,组织越来越希望变得更加敏捷。也许是因为损失:损失客户、员工、市场份额或品牌价值。也可能是出于“攀比”的需要,希望像亚马逊或Netflix一样酷。对于许多希望变得“更敏捷”的组织来说,他们实施敏捷转型的理由都是一样的。

然而,对于许多组织来说,变得“更敏捷”的旅程开始时充满了错误,利益干系人不满意,领导者烦恼而困惑。变得敏捷是很困难的,不仅仅是因为敏捷本身,实际上,这是因为任何改变对于组织来说都是很困难的。尼古拉·马基雅维利说过这样一句话:

没有什么事比推行新秩序更难以掌控、更充满风险、更难以成功了。——《君主论》(1532)

而敏捷转型就是要建立一种新秩序,是比采用一种新方法或过程框架更根本的变革。世界著名经济学家Carlota Perez将这种变化描述为对数字时代的常识性反应。

如今,没有人会提出一个集中式的、僵化的、自上而下的组织结构,在这种结构中,除了通过老板之外,你无法跨职能进行沟通。然而,这正是Alfred Sloan在通用汽车创立的结构,在他那个时代占据了很大优势。借助现如今的通信和有弹性的技术,灵活的创造性网络更有意义,会产生更大的生产力。

Perez继续写道,上一个时代的重点是大规模生产。从本质上讲,它与数字化生产是不同的。大规模生产关注的是降低单位成本,通过工艺优化、一致性、标准化提高质量。另一方面,数字化关注的是一个单位的规模,在这个单位中,所有的问题、解决方案和最终的价值流都是独一无二的。但是,有多少组织仍然使用同样的大规模生产模式来管理他们的数字化产品?对于结果、工作、团队和管理,敏捷时代都需要一种不同的方法。

关注结果——为业务价值负责

敏捷团队不是专注于以最具成本效益、一致性、风险趋避的方式完成工作,而是专注于以最有效的方式交付价值。他们关注的不是工作,而是他们想要交付的结果。Scrum是世界上最流行的敏捷框架,其方法是以实验为依据的。因此,问题被分解成小的实验,通过密切观察来确定哪一项可能会导致变化。小批量的工作加上关注价值的需要意味着:

  • 所有权成为最优先考虑的事情——在大多数传统的组织中,决策是以一种缓慢而一致的方式做出的。使用文档保存详细信息,通过签名确保每个人都知道涉及到谁。变更被视为一个问题,涉及昂贵的管理过程、审查委员会和升级方法。敏捷需要做出决策,需要根据反馈改进交付的工作。那需要所有权。
  • 价值需要能够清楚地理解和度量,这似乎是一个简单的要求——事实上,很多工作与价值之间没有明确的联系。度量也是非常困难的,因为组织需要设法解决可见性、透明性和所有权。
  • 团队必须与客户保持一致——通常,团队对他们与客户的关系知之甚少,即使他们可以从了解客户获得好处,但他们既没有与客户保持一致,也没有访问客户。客户由前端的业务、销售、营销和支持部门来管理。产品开发必须与这些组织合作以获取反馈。
  •  经常了解需要经常观察——对于数字化产品,这意味着要将它们交付给客户使用。频繁交付对从需求管理到产品测试的开发过程的每个部分都有巨大的影响。为了支持更小更频繁的变更,底层软件的架构方式也会改变。对于非数字产品或混合产品,频繁收集反馈的需要也改变了工作方式,团队更关注频繁地评审、模拟和测试。 

工作并非归管理者所有

在新的敏捷世界中,不可能要求人们在相同的广度或深度上完成特定的任务或计划。工作是由被授权的团队定义、管理和执行的,这些团队不关注任务,他们关注的是需要设法实现的结果。质量,包括技术债务在内,其处理方式与价值的处理方式相同,团队和业务在权衡的基础上做出明确、透明的决策。但是,从传统的管理工作转向更敏捷的方法,不仅需要管理人员走开,也需要组织:

  • 明确责任制和所有权——在大多数现代化组织中,每个人都有责任,但没有人负责。在敏捷组织中,很明确,团队要对结果负责,业务要决定团队在价值方面把重点放在哪里,组织要负责为团队的成功创造环境。通过明确责任和允许团队做出决策,敏捷组织可以大幅减少与传统自上而下的管理方法相关的大量浪费。
  • 管理层专注于建立适当的环境——许多管理者得到他们的职位是因为他们擅长工作。这导致了一种“家长主义”的文化,管理者告诉人们该做什么。对于简单的工作,这可能是有效的,但当工作变得复杂,流程变得多变,很难要求管理者始终在那里。因此,管理角色必须转变为教练和仆人式领导,帮助团队处理工作并关注结果。
  • 用产品替代项目——对于许多组织来说,工作是通过项目完成的,任何时候都有成千上万的项目在进行。每个项目都有资金、资源和大量的文档。人们在多个项目上工作,团队经常创建和解散。敏捷并不强迫组织不去做项目,而是鼓励组织采用一种更集中的、以团队为中心的工作方法。通过减少项目并转而向产品或客户看齐,团队可以更好地关注结果。其他的好处还有计划周期更简单、沟通的复杂性更低以及令人提心吊胆的上下文切换问题更少。项目仍然存在于跨多个客户/产品/结果边界的计划中,但它们不是常态。

团队是真实存在的

敏捷组织的核心是一系列自组织、有决策权的团队。他们拥有交付价值所需的所有合适的技能,并且,组织支持他们填补任何空白并帮助他们变得更好。在规模很大的情况下,这意味着团队的团队以及采用确保可以有效管理依赖关系的实践。但是与大规模生产不同的是,敏捷组织并不是从“把很多人投入到一个问题上”获益,而是鼓励更精简、“更聪明”的组织模型。组织可能需要通过以下方式改变他们对待团队的方式:

  • 专注于构建长期团队——对于组织来说,团队并不是一个新概念,事实上,对于许多组织来说,他们都非常喜欢把人安排到多个团队的理念。敏捷组织鼓励更专注的、以人为中心的模型,团队有身份认同和协调一致的成员。也就是说,工作被带到团队中,而不是围绕着工作形成团队。对于许多项目管理组织而言,这需要思维和流程的变革。 
  • 将工作管理与人员管理分离开来——当对你进行评估、决定你的奖金和晋升机会的人每天都和你一起工作时,很难做到透明。通过在敏捷团队中明确地将工作管理和人员管理分离开来,可以鼓励透明度和开放性。工作由团队管理,人才的发展与管理要么由某种社区或协会管理,要么由更传统的管理层管理。
  • 组织结构逐步向客户演化——对于许多组织来说,个人与应用程序一致,而这些应用程序在许多不同的客户或价值上下文中被重用。这就导致了每件事都会相互影响的复杂性。现代化的敏捷企业结构关注的是针对敏捷性进行优化。这可能意味着有些东西是重复的,单个应用程序的总拥有成本可能更高,但最终响应市场需求的价值超过了这个成本。优化根据其在栈中的位置进行,就像之前修改磁盘空间或整理的成本那样。
  • 多样性很重要——要应对复杂的问题,需要有经验的团队具有各种不同的观点和技能。意见、想法和解决方案的多样性对实现价值至关重要。但是,对于许多组织来说,团队边界重新加强了部门、系统和经验的边界。对于敏捷地开展工作,对于组织交付优秀的客户解决方案,构建挑战现状、看上去大不相同的多样化团队是很重要的。

敏捷转型的五项挑战

进入“新秩序”并不容易,许多组织已经开始了采用Scrum的旅程,并且正在考虑扩展框架,如LeSS、SAFe和Nexus,以及像Spotify这样的组织模型。遗憾的是,没有一种通用的方法可以将组织“转换”成敏捷的数字原生企业。查看组织框架和扩展模型是很好的工具,但只是其中的一部分,因为这一举措需要更全面的敏捷方法。也不能将其视为是用一种方法代替另一种方法,而应该看成是对于组织市场响应和价值交付方式而言更基本的东西。组织应该专注于5个广泛的挑战。

  1. 通过强大的领导力来支持和保护敏捷文化
  2. 帮助团队和利益干系人实现自组织
  3. 借助结果(而不是输出)来管理项目集合
  4. 系统性消除敏捷团队面临的浪费和延迟源
  5. 通过频繁反馈(检查和调整)度量和改进交付的价值

通过强大的领导力来支持和保护敏捷文化

组织文化是由组织制定的工作规范来定义的。领导者在行动和语言上定义并强化了这些规范。可以体现敏捷价值并强化其原则的领导者对任何转型都至关重要。例如,敏捷需要一种持续的学习和理解方法,但是,如果领导者专注于错误和责任分摊,那么很可能任何经验性过程都不会奏效。

帮助团队和利益干系人实现自组织

创建一个环境,使团队自组织并有权做出交付价值决策是敏捷的基础。遗憾的是,仅仅告诉团队他们获得了授权,并且可以自组织,这并不是引入这些理念的有效方法。相反,变革需要渐进引入,而类似管理3.0中的“授权板(Delegation Board)”这样的实践可以帮助团队慢慢获得主动地位。 

借助结果(而不是输出)来管理项目集合

和任何事情一样,敏捷只会和你关注的结果一样好。通过构建一个关注客户成果而不是工作的敏捷企业,你不仅可以实现更好的一致性,而且还可以推动一个清晰的愿景和目标。传统的组织总是关注系统,只有组织的一小部分与客户和他们所追求的结果联系在一起。现代化的敏捷企业把结果作为客户需求的核心,让每个人都对结果负责。

系统性消除敏捷团队面临的浪费和延迟源

浪费不是效率的敌人,而是价值的敌人。敏捷团队的浪费是任何阻止他们交付价值和改进的东西。诸如移交给外部部门这样的浪费浪费了花在审查会议上的时间。要变得更敏捷,把一切都放在“清除浪费”的议程上,没有什么是“一成不变”的。这意味着,诸如财务、审计和遵从性之类的组织需要成为变革的一部分,使他们以变革的视角审查现有的流程。规划通常是一个存在浪费的领域,长期的规划周期和变更管理过程占用了关键利益干系人和交付团队的宝贵时间。在Scrum中,浪费的管理是通过在每日Scrum中把它们透明化,并在冲刺评审和回顾中讨论改进。但是,除了任何特定的框架之外,敏捷团队都以学习和改进的眼光看待一切。他们也有挑战现状的勇气。

通过频繁反馈(检查和调整)度量和改进交付的价值

如果你打算通过衡量一件事来确定一个企业是否敏捷,那就是他们多久一次让他们的客户、利益干系人和团队来检查交付项。获得关于所交付内容的真实使用数据,以及创建最简单的东西以获得反馈,这是敏捷的基础。以客户为中心的敏捷组织亚马逊以每11.6秒交付一次软件而闻名。不是因为它想要增加更多的功能,而是因为它想和客户一起尝试新的想法,并得到客户的反馈。

小结

这似乎有点讽刺意味,但许多组织认为向敏捷转型就像使用传统的方法爬山一样。制定计划,寻找资源,然后执行。但是,成为一个敏捷企业不仅仅是采用一个特定的过程框架或者改变职位名称。这是你对市场响应方式的根本性改变。组织模型、过程、工具,甚至是基础产品都会根据客户、市场和利益干系人的需求而频繁地改变。敏捷企业的核心是一个以客户为中心的学习型组织。Peter Senge在其著作《The Fifth Discipline – The Art & Practice Of The Learning Organization》中描述了组织专注于学习的必要性。

“唯一可持续的竞争优势是一个组织比竞争者更快速地学习的能力”。

最终,通过专注于敏捷领导力、自组织、以客户结果为中心、消除浪费以及了解组织文化并频繁交付这5项挑战,组织将变得更加专注于学习并变得更加敏捷。

作者简介

Dave West是Scrum.org的产品负责人和CEO。他经常在主要行业会议上发表主题演讲,并发表了许多文章和研究报告。他还与人合著了两本书《The Nexus Framework For Scaling Scrum》和《面向对象的分析与设计》。他领导了IBM/Rational Rational Unified Process(RUP)的开发。在IBM/Rational之后,West重新回到了咨询行业,并负责Ivar Jacobson咨询公司北美分公司的管理。然后,作为副总裁兼Forrester Research研究总监,他负责软件开发和交付实践。在加入Scrum.org之前,他是Tasktop的首席产品官,负责产品管理、工程和架构。作为公司高管团队的一员,他帮助Tasktop从一个服务公司成长为一家团队将近100人的、VC支持的产品公司。

查看英文原文:https://www.infoq.com/articles/managing-next-century-agile

 




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/managing-next-century-agile

银行业中的弹性系统

本文要点

  • 冗余和隔离是同一枚硬币的两面。
  • 防范自己的Bug,而不仅仅是环境因素。
  • 减速比崩溃更容易跨越服务边界。
  • 同步API为故障传播提供了充足的机会——务必避免!
  • 已建立的云模式是有效的,即使没有调度程序和网格——第一天的架构应该简单到极点。

弹性是容忍失败,而不是消除它。

你不能把所有的时间都花在避免失败上。如果你这样做了,你将构建出一个脆弱到无可救药的系统。如果你真希望建立一个弹性系统,就必须构建一个能够吸收冲击并继续或恢复的系统。

在“斯塔林银行(Starling Bank)”,在现有银行公共服务大量中断的背景下,我们在一年的时间里从零开始创建了一家银行;我们知道,我们需要可靠的弹性方法。我们需要来自混沌工程的保障,以及使最好的创业公司得以茁壮成长的对简单性和严格优先级的执着追求。

以下是我们的弹性方法背后的原则和信念。

顺便说一下,我们的方法有一些特性,我在这里不做介绍,但它们仍然是必不可少的:

  • 混沌工程——因为弹性必须测试;
  • 监控——因为弹性需要可支持性;
  • 事件响应——因为弹性适用于系统和运行它的组织。

相反,我们关注的是从基础设施往上的弹性架构。

弹性架构

为客户提供弹性服务意味着,要确保在故障发生时,受错误影响的系统部分与系统整体相比很小。

有两种方法可以确保这一点。冗余是指确保系统作为一个整体扩展到故障范围之外。不管有多少受损,我们都有其他备用的。隔离是指确保故障局限在一个很小的范围内,而不能扩展到我们系统的边界。

无论你如何设计系统,都必须对这两个问题有很好的答案。有鉴于此,你必须针对你能想象到的每一个错误在脑海中测试你的设计。

请考虑以下方面的失败,希望对你有所帮助:

  • 基础设施层故障(如网络故障)以及应用程序层的故障(如未捕获的异常或终止);
  • 我们构建的软件的内部故障(由我们即Bug导致)以及外部故障(由其他人如非法消息导致)

仅仅假定通过测试可以消除内部故障是不够的。保护自己不受外界干扰和保护自己不受自己干扰一样重要。

设计的简单性是影响失败归因难易程度的最重要因素,所以总是选择满足你需求的最简单设计。

冗余

基础设施冗余在云中很容易实现。基础架构即代码使我们在创建多个时可以和创建一个一样容易。

云提供商,如AWS和GCP,提供了IaaS原语,如负载均衡器缩放组,并在文档中清楚记录了它们的使用模式。像Kubernetes这样的执行环境提供了部署复制控制器等资源,其中,复制控制器持续保证服务的多个副本正在运行并可用。无服务器技术将在不进行任何配置的情况下为你扩展服务。

但也有一些限制。

状态是老敌人了。当实例假设本地状态准确时,扩展服务的难度就大许多。要么通过一个高可用的数据存储和外部共享状态,要么引入集群协调机制来保证每个实例的本地状况与对等实例的一致,总之,将服务器转化为分布式缓存。

我的建议是,至少对于创业公司来说,在第一天要保持非常简单。数据库用于共享状态。用它共享所有状态,直到达到其极限。本地内存仅用于瞬态状态。这为你提供了一个简洁的“不可变的”计算层和一个具有明确操作需求的数据库。你知道,你需要在某个时候改进这个基础设施,同步修改架构并监控指标。到那一天,你就从简单的扩展和冗余受益了。

无服务器环境通常提供一个无状态函数服务,并针对状态提供单独的数据库服务,这实际上是默认提供了简单巧妙的分离。

共享资源限制可能是另外一个问题。当后端数据存储仅支持接受3个连接时,将服务扩展到10个实例是没有意义的。事实上,当服务公开其他组件以加载它们无法支持的组件时,扩展服务可能是危险的。增加系统某一部分的性能会降低系统的整体性能。实际上,如果没有高强度的测试,你就无法了解所有这些限制。

隔离

在云基础设施层,AWS在每个区域内提供单独的可用区,在基础设施组件之间提供强隔离。负载均衡器和伸缩组可以跨越多个可用区。

在AWS中已建立的构建模式可以确保你做好基础工作。其他云也有类似的功能。

在应用程序层,微服务自包含系统、甚至传统的SOA都是可以在服务之间引入强隔离带的设计方法,允许这些组件独立失败,而不影响整体的服务能力。

如果服务的单个实例崩溃,则服务不会中断。如果服务的每个实例都崩溃,客户体验可能会在某种程度上受到影响,但其他服务必须继续运行。

使用这种模式,系统分割得越细,单个服务故障影响的半径就越小。但还是那句话,魔鬼是在细节当中。服务之间可以通过许多微妙的方式相互依赖,这些方式跨越服务边界,使得错误会在系统中扩散。当服务密切相关时,通常可以简单地将它们视为单个服务,并将它们构建为单个服务。

有些方式可能不太明显,比如隐藏协议;服务实例可能通过负责Master选举的集群协议进行连接,或者通过针对每个事务(如果你参与了这类事务)进行网络投票的两阶段提交协议。工程师们常常会完全脱离这些网络交互,但它们用错误可以传播的方式将服务连接在一起。

就像在生活中一样,同居是一个不可掉以轻心的决定。如果你在同一个实例上运行多个服务,无论是经过深思熟虑的静态分组,还是使用像Kubernetes这样的调度器,这些服务的隔离程度都要比在单独的机器上低。它们都受许多相同故障条件的影响——尤其是硬件故障。

如果服务X、Y和Z的实例总是在同一台主机上一起运行,那么如果X可以任意运行并“毒害”主机,那么不管有多少个实例,X的邻居都是Y和Z。把它们分到一组,就侵蚀了服务X、Y、Z之间的隔离——即使你的技术应该保证这种“中毒”情况不会发生。

调度程序可以通过避免在任何地方部署相同的服务集来缓解这一问题。因此,如果一个有Bug的服务毒害了它的主机,你不会看到任何其他服务的完全失败,而是在更广泛的服务范围内产生较为分散的局部影响,而这可能根本不会影响客户体验。

在我们推出的架构中,斯塔林银行选择了一个简单的单服务EC2实例模型。这是一种权衡,特别注重简单性而不是经济性,但也提供了非常强的隔离。失去一个实例是很难察觉的。即使我们部署了一个流氓服务,对它的主机做了一些有害的事情,它也不容易影响到其他服务。

在应用层代码中传播错误的方法也很多。

也许最有害的因素是时间本身

在任何事务型系统中,时间都是最有价值的资源。即使你没有在处理器上进行主动调度,你也可能在完成工作的时间内持有重要的资源:连接、锁、文件、套接字。如果你磨磨蹭蹭,就会让别人挨饿。如果另一个线程无法继续,它可能不会释放它所持有的资源。它可能迫使其他服务进入等待状态,在整个系统中传播不良影响。

虽然死锁经常被描述为并发编程中的邪恶反派,但在现实中,由于事务运行缓慢而导致的资源匮乏可能是一个更常见而又同样严重的问题。

这一点太容易忽视了。工程师的第一直觉是安全而正确的:获取锁,进入一个事务,也许简单考虑了下超时设置然后就跳过了它——(工程师讨厌任何看起来随意的东西,对于如何处理超时,会有尴尬的选择)……日常开发中的这些简单诱惑能给生产环境造成严重伤害。

不能允许等待和延迟在服务之间传播。但是,除非你对这种不当行为有一些全局的预防措施,否则不难想象,你的系统容易受到攻击。你有固定大小的数据库连接池吗?或者线程池?你确定在进行REST调用时从不持有数据库连接吗?如果这样做了,当网络通信降级时,是否会耗尽连接池?其他还有什么会耗费时间?那些你几乎看不到的东西呢,比如日志调用?或者,你可能有一些需要反复收集的指标需要数据库访问,但由于池中的连接被用光了,所以数据库访问开始失败,导致大量的垃圾被写到日志中?然后,你也许会突破日志架构的限制,从而失去对正在发生的一切的可见性。构建一个噩梦般的场景是一件很有趣的事情,而这个场景是以一点点的拖延开始的。

预防措施有很多:断路器、“隔板(bulkheads)”、重试设置、最后传播期限……还有一些库可以帮助你在软件(hystrixresilience4j)中实现这些模式,也有一些服务网格或中间件(istioconduitlinkerd)在底层提供了其中部分模式。但如果不投入时间和精力,它们都不会做正确的事情。和往常一样,任何代码的性能和故障模式都将反馈给工程师。

同步调用借用了别人的时间。而且,作为一个同步API,按照合理的设计原则,你通常不知道这段时间对调用者有多么宝贵,也不知道它们多么容易受你的拖延或失败影响。你把他们扣为了人质。因此,我们更喜欢在服务之间使用异步API,并且只在绝对必要或者是非常简单的只读调用中使用同步API。

前端可以进行“乐观”的UI更新,而不是等待确认,并在离线时显示过时的信息。在大多数情况下,根据过时的信息进行决策需要付出一定的代价,但这种代价不一定很高。Pat Helland曾经写道:计算由记忆、猜测和道歉组成。当系统表示偏离现实时总是有代价的,当现实在你背后发生变化时,它总会在某个时候偏离现实。在分布式系统中没有真正的“现在”。在决定需要完美的事务语义或同步响应之前,评估下“错误”的代价。

对于银行系统来说,容忍失败意味着容忍失败而不丢失信息。因此,虽然实现异步系统不一定需要队列,但你可能希望系统作为一个整体表现出一些类似队列的属性——至少一次最多一次交付,即使存在错误。通过这种方式,你可以确保某些服务始终拥有数据或命令的所有权。

你可以通过在服务中同时使用幂等性和追踪处理来达到这两个目的(如斯塔林的“DITTO”架构——有很多自治服务不断尝试做互相幂等的事情),或使用队列保证至少一次,使用幂等载荷保证至多一次(如Nubank的Kafka基础设施)、或设法把它们都委托给“企业服务总线”(如许多传统银行的架构)。

使用这些技术,完全有可能在异步交互服务的基础上创建响应性应用程序。

总结

编写弹性系统比以往任何时候都容易。在前12个月的运营中,斯塔林银行经历了许多局部故障和系统部分退化——从来没有出现过整个系统不可用。这主要是因为我们在每个层面上都强调冗余和隔离。

我们设计了一个能够容忍服务中断的架构,并特别重视这样一种观点,即慢服务对最终用户的威胁可能比死服务更大。

如果一开始我们对于上面列出的各项——混沌工程、监控和事件响应——没有可靠的方法,那也没有关系。但这得再一天介绍了。

关于作者

Greg Hawkins 是技术、金融科技、云计算和DevOps等领域的一名独立顾问。他在2016年至2018年期间担任斯塔林银行的首席技术官,这是英国一家仅限移动端的挑战者银行。在此期间,这家金融科技初创企业获得了银行牌照,两大移动平台上的下载量都突破10万次。现在,他仍然是斯塔林银行的高级顾问。斯塔林从零开始构建了全栈银行系统,成为英国第一个完全部署在云上、普通公众可以使用的经常账户,并满足了适用于零售银行的所有监管、安全和可用性预期。

查看英文原文:Resilient Systems in Banking




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/resilient-banking-systems

苏宁蛙测&SAT在自动化测试方面的应用

前言

2018 年苏宁易购提出了智慧零售大开发战略,业务快速发展对苏宁的 IT 技术提出了更高的要求,其中一个重要的环节就是加快软件版本的上线步伐,伴随着软件的频繁快速上线迭代必然存在巨大的测试压力。

通常情况下,软件测试的工作量很大。而频繁版本迭代中,针对老功能的回归测试是重复性的且这类测试比较耗时耗力,并要求做准确细致的工作,这样,计算机就比人更适合完成任务。另一方面,手工测试存在诸多的局限性。于是,就诞生了软件自动化测试这个领域。软件自动化测试是相对手工测试而存在的,主要是通过所开发的软件测试工具、脚本等来实现。

2011年以前,针对自动化测试,苏宁各业务部门会安排一有代码能力的测试人员,全职编写自动化脚本,有人用java、有人用python,有人用ruby等等,并没有一个体系性、标准化、流程化的规范,因此也导致脚本维护成本高,复用性低,同时对测试人员的技能门槛比较高。

在这样的背景下,开始了我们苏宁自动化测试实践之路。下面我来为大家详细介绍。

1 SAT是什么

苏宁自动化测试工具(Suning Automation Tester)——简称”SAT”,是苏宁测试平台研发中心自主研发的集WEB页面、HTTP及RSF协议、手机终端、数据库操作、LINUX操作等方面的于一体的自动化测试工具。

SAT是基于RCP平台上实现自动化用例设计和自动化执行的工具。它采用自动化测试架构中的关键字驱动(Keyword)思想,使测试设计和测试实现分离,将实现不同公共组件类、业务类Keyword集成到一个用例中运行,也最大限度地实现Keyword共享,降低测试组重复开发的工作量,使测试人员可以更关注业务本身的测试;另外工具提供了完善的日志和测试报告功能,方便用户查看用例执行日志和批量执行测试报告;最大限度地降低工具使用门槛,提高了其自动化开发、测试效率。

1.1  应用范围

  • Web应用软件产品测试
  • 移动应用产品自动化测试,支持移动端Android、iOS两大主流操作系统
  • 协议接口测试(HTTP、RSF、MQ)
  • 数据库操作
  • 支持SAP类型测试

1.2  特点优势

  • 浏览器/移动终端录制功能,自动生成脚本
  • 拖拽关键字快速生成测试脚本,降低自动化门槛
  • 业务关键字自由配置,满足业务扩展
  • 测试数据独立存储,维护成本较低
  • 测试脚本等相关资产可共享协作,提高测试工作效率

2 蛙测是什么

蛙测是苏宁自主研发的一套综合测试服务平台,是面向软件从业者的一体化测试解决方案,包含移动端 (Android&iOS)自动化测试和专项测试、 PC端多浏览器兼容性测试、接口协议自动化测试,以及性能测试和安全测试的云测平台,解决广大开发者和测试者在应用研发过程中面临的成本、技术和效率问题,提供7×24全天候服务。

平台核心服务有功能测试、自动化测试、性能测试、稳定性测试以及安全测试等,对应用软件提供360度全方位自动化检测,有效节约成本,提高了版本回归测试效率,为苏宁软件质量保驾护航。

3 蛙测自动化方面特点

  • 移动设备/PC终端资源共享,节约成本

App应用都需要在主流机型上测试验证,需要购买较多移动设备,采用蛙测平台后,可以做到移动设备资源共享。

PC端测试,解决本地编辑、在线编辑、云端执行的冲突和效率问题,蛙测提供了测试集群,根据有效规则指定测试执行器消化测试任务。

  • 测试计划随时创建,云端多机并行执行,多终端支持,执行计划灵活设置

测试资源池化,7×24全天候服务,立即执行、定时/循环定时执行、条件触发执行等不同执行计划按需设置,多云端设备串行、并行测试,效率高,报告日志实时查看,持续追踪。

  • 多手段自动生成测试数据,高效高质量

构造数据手段丰富,支持SQL语句、UI和接口自动化,无逢对接企业现有逻辑,百余台服务器7*24小时提供服务,保障数据的高效生成。数据构造集中管理,避免各自为战,严谨的数据复检功能。

  • Mock测试,设置方便灵活,千人千面,满足多种业务场景

支持用户创建全局和请求级桩服务,支持HTTP、ESB、RPC 等协议 Mock,对代码无侵入,支持同步、异步以及回调场景等功能,提供调用日志查询,满足多种应用场景。同时与服务管理平台、一建站系统打通,让接口测试更便捷,更简单。

4 蛙测&SAT技术架构

蛙测的技术架构


5 蛙测&SAT在自动化测试实际应用

SAT的技术框架


蛙测平台的技术框架

5.1  自动化测试脚本实际应用

5.1.1  数据定义的应用

全局变量:基于对业务的理解抽取公共字段定义变量

局部变量:根据数据的复杂度决定使用组合关键字定义变量,或用表格定义数据实现用例数据分离

5.1.2  组合关键字的应用

多操作步骤封装为一场景步骤关键字,大大减少了测试脚本的步骤数,提升了脚本可读性,且该组合关键字后续可重复拖拽使用,有效提高了脚本编写效率,减少了维护成本。

操作:选择合适的场景—>封装组合关键字—>拖拽组合关键字至测试用例

选择合适场景封装组合关键字

引用组合关键字后脚本测试步骤展示:

5.1.3  原子用例的应用

原子用例的设计为实现高可维护性自动化提供一种解决方案,单场景复用,便于测试场景的有效列举。

操作:选择合适用例—>设置原子用例—>拖拽原子测试用例至测试用例。

用例树区分展示原子用例、普通用例、已引用原子用例的用例;

业务用例中拖拽引用原子案例,根据业务场景多次引用相应场景原子用例,编写对应场景用例

5.1.4  应用效果

基于对业务的理解抽取公共数据、公共逻辑实现组合关键字、原子用例,自动化脚本优势可充分利用并放大实际应用效果

  • 脚本可读性高

降低测试用例的冗余度,大大减少步骤数,也提高可读性

减少编写案例的工作量

  • 公共逻辑可复用性强

组合关键字/原子用例存在共性,可供重复引用

便于测试场景的有效列举

  • 脚本可扩展性高/维护成本低

需求发生变更,只要维护少量组合关键字/原子用例

大大降低维护成本

无论业务如何变化,合理使用好组合关键字、原子用例,抽取数据做好数据定义,这两项能为大家的自动化测试工作保驾护航。

(Tips:工具提供的只是手段,最核心的还是需要大家深入理解、挖掘业务)

5.2  mock实际应用

桩发展历程:最初SAT端只支持请求级别桩,但是异步的rsf请求中,找桩标记无法自动下传,需要服务修改代码把找桩标记下传后才可使用。

后经过多方研讨,决定把桩服务升级应用于蛙测平台,通过对接口设置挡板的方式,构建测试数据实现千人千面,也就有了现在的全局桩、UI 桩、回调桩等全面桩。

5.2.1  请求调用

脚本中rsf埋桩demo展示示例:

SAT端桩响应条件设置设置桩响应条件,填写请求报文相应属性路径下,参数的属性值,接口请求时,根据响应条件的匹配,返回相应设置的模拟桩,即做到某桩在某请求条件满足响应条件下生效,真正做到千人(桩响应条件)千面(桩响应报文)。

SAT端桩响应条件设置

蛙测端桩响应条件设置。

5.2.3  MQ接收

MQ接收的场景一般分为以下两类:

场景一:通过MQ队列接收数据之后直接存库;

场景二:通过MQ队列接收数据后需要继续调用处理其他资源,然后入库/入缓存等操作。

自动化实现:

截图中测试步骤列举的为MQ收到消息需要调用其他资源需要用到的一些关键字。

MQ场景二涉及调用其它资源,为独立测试该场景,mock相应依赖,因此引入全局桩的概念。

5.2.3  应用效果

请求级别桩优势:

  • 桩数据在本地,对蛙测依赖小
  • 通过SAT日志就能定位问题,方便简洁

全局桩优势:

  • 支持场景丰富,同步/异步请求都支持,且不需要被测系统嵌入代码
  • 通过构造请求报文的多样性,实现千人千面
  • 蛙测支持多机并行

根据请求桩与全局桩存在不同优势,结合业务需求相应结合使用,实现Mock测试,摆脱被测系统间依赖,提高测试质量及效率,同时成功解决测试人员、开发人员在测试和研发过程中,数据构造、环境依赖等痛点,大大提高了生产效率,提高测试场景的覆盖率,保障了业务版本上线的质量。

6 蛙测& SAT解决的问题和实现的价值

6.1  解决的问题

  • 用户手工测试耗时长效率低
  • 自动化脚本写作门槛高
  • 自动化脚本维护成本高,复用率低
  • 用户自动化执行需占用本机的资源
  • 用户缺少特定测试设备
  • 单机执行并发度低,测试耗时久,效率低下
  • 本地执行后测试结果无法有效追踪
  • 接口测试时依赖方不可用,测试人员无法提前介入测试
  • 构造异常数据流程复杂,无法很快生成,影响测试效率
  • 依赖方涉及到现金交易,测试成本高

6.2 实现的价值

  • 测试资源池化,多浏览器、多终端设备、稀缺资源统一管理
  • 降低测试成本,测试设备在云端,共享使用
  • 多维度并发执行,提高测试效率
  • 云端任务执行,测试结果持续追踪,
  • 摆脱被测系统间依赖,自已的测试自己做主
  • 数据构造集中管理,统一调度

7 总结

目前蛙测&SAT在苏宁集团各业态已全面应用,包含苏宁易购、物流、金融、科技、置业、文创、体育和投资八大体系近万名IT研发人员。此间测试资产积累效果显著,每月自动化测试执行案例数超过100万,自动化测试步骤数超过3000万行。

蛙测团队一直在努力,在测试技术方向,持续探索,永不停歇!我们的宗旨:提供专业、简单、高效的测试服务!

欢迎大家多多关注、共同交流!

作者简介

卢烨,苏宁云测试平台技术经理,2013 年加入苏宁,一直从事测试工具与平台的测试、产品工作,始终专注于测试技术、测试效率等相关领域。精通自动化测试、测试管理方面新技术和新理念,同时对自动化测试、测试管理在实际测试活动中的应用实践积累了比较丰富的经验。




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/articles/suning-test-sat

NoSQL数据库敏捷数据模型

在近日举行的2018年数据架构峰会上,Hackolade首席执行官Pascal Desmarets谈了NoSQL数据库的敏捷建模。他说,在NoSQL数据库中,由于没有规范化约束,数据建模变得更加重要。非结构化的多态大数据在数据治理和监管(GDPR和PII)以及利用积累的信息的能力方面都提出了挑战。

Desmarets还谈到了数据建模如何帮助企业从RDBMS迁移到NoSQL。在关系数据库和NoSQL数据库中,数据建模的好处包括提高应用程序质量,改善数据质量、GDPR&隐私身份信息以及商业智能。

团队应该根据需求选择合适的NoSQL数据库。例如,如果你需要管理简单的模式和快速地读写而不需要频繁地更新,那么就选择键-值存储。如果你需要支持复杂查询的灵活模式,请选择文档数据存储。面向列的数据库很适合读取速度相对较低而写入速度极高的情况。图数据库更适合于需要在数据点之间进行遍历的应用程序,因为你需要能够存储每个数据点的属性以及它们之间的关系。

他谈到了传统的数据建模过程以及我们如何从数据建模过渡到模式设计方法。概念数据模型已经被领域驱动设计(DDD)所取代,不再需要逻辑数据模型,物理数据模型则被物理模式设计所取代。

在敏捷开发过程中,数据建模在过程的每个步骤中都有作用,包括在生产环境中。数据建模工作成为多个项目涉众之间的共享责任和对话。

他还说,领域驱动设计(DDD)和NoSQL像是为彼此量身设计的,DDD语言和NoSQL数据库的概念直接吻合。他认为,在整个的策略、过程、体系结构和技术中,一致性是必要的,因为将所有这些原则一起应用比孤立地应用一两项原则更可取:领域驱动设计、敏捷开发、“以数据为中心(Data-Centricity)”、微服务、事件驱动的体系结构、NoSQL、DevOps和云。

InfoQ采访了Desmarets,内容涉及NoSQL数据库数据建模及大数据管理的最佳实践。

InfoQ:每种NoSQL数据库类型的数据建模方法都不同吗,比如像Cassandra这样的时间序列数据库和像Neo4j这样的图数据库?

Pascal Desmarets:总体的方法非常相似,但是实现可能有很大的不同。为了利用NoSQL的优点,设计特定于应用程序的数据模型是非常重要的,这样就可以以优化查询性能的方式存储信息。对于那些几十年来一直使用与应用程序无关的数据建模原则的人来说,这种思维转变可能是一个挑战。对于我们中的许多人来说,规范化规则已经成为第二天性,我们必须强迫自己应用查询驱动的方法来为NoSQL数据库进行模式设计。

查询驱动的方法对于所有NoSQL数据库家族都非常相似。但是,当涉及到每种技术的模式设计的具体方面时,区别最大的是图数据库和NoSQL DB其他三个家族之间的差异。图数据库的特点是:在执行查询时,图遍历性能要求任何其他技术中的属性在图数据库中都可以提升为实体(或节点)的状态。

另外,每个NoSQL数据库家族中也存在差异。例如,对于图数据库,属性图DB和RDF三元存储之间有根本的区别。在JSON文档数据库中,你会发现CouchbaseMongoDB之间的存储结构存在差异。类似地,HBaseCassandra有非常不同的数据存储方法。

InfoQ:您能谈谈NoSQL数据库敏捷建模中的一些最佳实践吗?

Desmartes:几十年来,正如我们所熟知的那样,数据建模在敏捷开发环境中承受着巨大的压力。尽管试图使数据建模更加敏捷,但它经常被视为两周冲刺中速度和节奏的瓶颈。世界各地的数据建模者都感觉被排除在这个过程之外。事实上,某种形式的模式设计是必不可少的,就是说,需要重新设计数据建模以保持其重要意义。

首先,在整个开发冲刺和应用程序生命周期中,数据建模需要成为一个迭代过程,而不是一项繁重的前端任务。

数据建模还需要成为数据建模者(他们擅长抽象他们对业务的理解)和开发人员(他们真正理解如何将需求转换成代码)之间的协作过程。

这就要求数据建模人员成为Scrum团队不可或缺的一部分。

该方法需要适应开发技术和技术栈,特别是前面描述的查询驱动和特定于应用程序的方法。它必须结合领域驱动设计、用户体验和业务规则流程图以及屏幕线框图和报表,才能获得在设计模式时需要考虑的应用程序查询。

最后,我们需要能够灵活适应新环境的下一代工具!

他还说,在相当长的一段时间里,NoSQL数据库供应商通过使用“无模式”或“非关系型”等术语创造了一种差异化和轰动效应。但是,NoSQL数据库是如此的灵活和强大,没有经验的用户如果不应用一些严格的技术,就很容易陷入麻烦。现在,供应商意识到,为了将他们的解决方案卖给企业,更明智的做法是使用术语“动态模式”。在使用NoSQL时,数据建模(或模式设计)实际上比关系数据库更重要。我们只是需要一种不同于以往的数据建模方法。数据建模者应该拥抱敏捷开发,并学习新技术栈,证明它们在这个过程中增加了价值。

查看英文原文:Agile Data Modeling for NoSQL Databases




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/agile-data-modeling-nosql

React Native重构路线图发布!

今年6月中旬,FB曾宣布他们将大规模重构React Native,目的是为了让React Native更轻量,更适应 JavaScript 生态圈的发展。最近,Facebook正式公开了他们计划的一些细节:

1. 让RN的GitHub存贮库更健康,issues和 pull请求将及时得到处理;

  • 提高测试覆盖率

  • 从Facebook代码存储库同步的Commits不能违背开源测试的准则

  • 提升社区的贡献量

2. 稳定API,使之更容易与开源依赖项交互;

  • Facebook使用与开源相同的公共API

  • React Native将遵循语义版本标准

3. 让生态系统更加有活力,社区将提供高质量的ViewManagers、native modules、多平台支持;

4. 文档优化,专注于帮助用户创建高质量的体验,以及最新的API参考文档。

核心目标

RN团队的目标是通过删除非核心和无用的组件来简化RN,将非核心组件转移到社区,让开发者使用更加便捷,他们目前已经决定将这些组件的所有权为社区所拥有

WebView就是其中的一个实例

与此同时,RN团队还在开发一个工作流,它将允许内部团队在存储库中删除这些组件后还能够继续使用它们。

开源内部开发工具

由于Facebook内部开发人员用的是内部开发工具,开发体验与开源的完全不同,在开源社区受欢迎的那些工具可能并没有被Facebook开发人员使用,在某些情况下,Facebook团队已经习惯使用仅限Facebook内部使用的工具,这种内外差异可能会很大程度影响他们接下来的重构工作。

为此,他们做了如下改进:

  • 开源JSI,使社区能够使用自己的JavaScript VMs,从RN的初始版本中替换现有的JavaScriptCore,有关JSI的信息,他们未来会公布,现在你可以先通过React Conf大会上的演讲视频了解。

  • 支持Android上的64位库

  • 新架构下支持调试

  • 改进对CocoaPods、Gradle、Maven和新Xcode构建系统的支持

建设测试基础设施

当Facebook工程师发布代码时,如果通过所有测试,则认为代码可以上线了,这些测试可以判断某些改动是否会破坏React Native,由于Facebook使用React Native的方式与外部存在差异,他们可能在不知不觉中破坏了开源环境中的React Native。

为此,Facebook将支持内部测试,确保它们在尽可能接近开源的环境中运行。这将有助于防止被破坏的代码开源。同时,他们还将致力于建设测试基础设施,以便在GitHub上更好地测试核心存储库,使未来的pull请求能够包含在测试里。

使用公共API

Facebook将通过公共API使用React Native,和开源一样,以减少无意间的破坏性更改,他们的目标是融合稳定的公共API,并在v1.0中采用语义版本控制标准。

加强沟通

React Native是GitHub上贡献者数量最多的开源项目之一(排名第二),未来,Facebook将继续致力于贡献者相关的举措,例如提高透明度和公开讨论。对新手来说,文档将是一个大问题,为此,RN将创建自动生成的API参考文档,改善用户体验。

RN团队称,这些项目将在明年完成,其中,JSI项目已经在进行中,其他的一些改进如简化RN,还需要更多的时间去完成,开发者有任何问题可以在提案中讨论

查看英文原文:http://facebook.github.io/react-native/blog/2018/11/01/oss-roadmap




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/react-native-roadmap

Google发布Fluid Annotation,数据标注速度提高三倍!

AI 前线导读: 支撑人工智能的崛起的背后不仅有科学家、程序员,还有 “农民工”。这些所谓的农民工就是数据标注员。在人工智能灼热与闪亮的背后,数据标注产业,作为做基础的支撑,却显得格外粗粝与拙朴。这个产业就是个“血汗工厂”,引用该产业的一个员工的说法:“人工智能就像是一个孩子,标注好的图片就像是孩子的食物,而我们就是制作食物的人,最苦最累的我们做了,成名的只是那些制造孩子的人。” 这话说得没有错。那么,我们能不能让机器解放这些数据标注员呢?Google AI 就推出了 Fluid Annotation ,旨在提高数据标注的能力。

基于现代深度学习的计算机视觉模型(如由 TensorFlow 对象检测 API 实现的模型)的性能取决于日益增大的标注训练数据集(如 Open Images)的可用性。然而,获得高质量的训练数据很快成为计算机视觉的主要瓶颈。对于像语义分割(semantic segmentation)这样的像素级预测任务尤为如此,语义分割在自动驾驶、机器人和图像搜索之类等有广泛的应用。实际上,传统的手动标注工具需要使用注释器仔细点击边界来勾勒出图像中每个对象,这种过程很令人乏味,如下面的视频所示。在 COCO+Stuff 数据集中标注一个图像需要 19 分钟,而完成整个数据集的标注需要 53000 个小时!

AI 前线注: 
使用 TensorFlow 对象检测 API 实现的计算机视觉模型可以参见《http://ai.googleblog.com/2017/06/supercharge-your-computer-vision-models.html》(https://ai.googleblog.com/2017/06/supercharge-your-computer-vision-models.html)。 
关于标准训练数据集 Open Images,可参见《Announcing Open Images V4 and the ECCV 2018 Open Images Challenge》(https://ai.googleblog.com/2018/04/announcing-open-images-v4-and-eccv-2018.html)。 
语义分割的应用可参见《Semantic Image Segmentation with DeepLab in TensorFlow》(https://ai.googleblog.com/2018/03/semantic-image-segmentation-with.html

视频地址:https://v.qq.com/x/page/t0761gtjon6.html

左图为 COCO 数据集的图像示例,右图为像素级语义标注。

我们将在 2018 ACM Multimedia Conference 会议的 Brave New Ideas 公开论文《 Fluid Annotation:用于完整图像标注的人机协作接口》(Fluid Annotation: A Human-Machine Collaboration Interface for Full Image Annotation),在这篇论文中,我们探讨了机器学习驱动的接口,用于标注图像中每个对象和背景区域的类标签与轮廓,从而将标注数据集的创建速度提高三倍。

AI 前线注: Fluid Annotation: A Human-Machine Collaboration Interface for Full Image Annotation 论文地址为:https://arxiv.org/abs/1806.07527

Fluid Annotation 从强语义分割模型的输出开始,人们要做标注工作,可以使用自然用户接口通过机器辅助编辑操作进行修改。我们的接口可以让标注者选择正确的内容和顺序,使他们能够有效地将精力集中在机器尚未知晓的内容上。

COCO 数据集中图像 Fluid Annotation 接口的可视化效果。

更确切地说,为了标注一张图像,我们首先通过预训练的语义分割模型(Mask R-CNN)来运行它。这将生成大约 1000 个带有类标签和置信度分数的图像片段。具有最高置信度的片段用于初始化标记,并将标记呈现给注释器。之后,注释器可以:(1)从机器生成的候选列表选择现有片段的标签。(2)添加一个片段来覆盖缺失的对象。机器识别出最可能预先生成的片段,通过这些片段,注释器可以滚动并选择最佳片段。(3)删除现有片段。(4)改变重叠片段的深度顺序。要更好地了解这个接口,请访问此网址 https://fluidann.appspot.com/ 来尝试 Demo(仅限于桌面)。

AI 前线注: Mask R-CNN 论文参见 https://arxiv.org/abs/1703.06870

在三幅COCO图像(左)分别使用传统手工标注(中)与 Fluid Annotation (右)的对比。虽然使用手工标注工具时,对象边界通常更精确,但标注差异的最大来源是由于人类注释器通常不同意确切的对象类。

Fluid Annotation 是使图像标注更快、更容易的第一步探索。在未来的工作中,我们的目标是改进对象边界的标注,通过加入更多的机器智能,使接口更快,最后扩展接口来处理以前看不到的类,而这些类最需要高效的数据收集。

查看英文原文: https://ai.googleblog.com/2018/10/fluid-annotation-exploratory-machine.html




文章来源:http://www.infoq.com

原文地址:http://www.infoq.com/cn/news/2018/11/google-fluid-annotation