草庐IT

详细教程丨如何利用Rancher和Kong实现服务网格?

RancherbySUSE 2023-03-28 原文
服务网格(Service mesh)是当前新兴的架构模式,越来越受到人们的青睐。与Kubernetes一起,服务网格可以形成一个强大的平台,它可以解决在微服务集群或服务基础设施上发现的高度分布式环境中出现的技术需求。服务网格是一个专门的基础设施层,用于促进微服务之间的服务到服务通信。

服务网格解决了基于微服务的应用中典型的通信需求,包括加密隧道、健康检查、断路器、负载均衡以及流量许可。如果离开微服务来解决这些需求,会导致开发过程中产生高昂的费用和耗时。

在本文中,我们将对服务网格架构模式解决的最常见的微服务通信需求进行概述。

微服务动态和内在挑战

当你意识到微服务实现了相当多的与最初分配给它们的业务逻辑无关的代码时,问题就出现了。此外,有可能你有多个微服务在非标准化的流程中实现了类似的功能。换句话说,微服务开发团队应该专注于业务逻辑,并将低级通信能力留给特定的层。

继续推进我们的方案,需要考虑微服务的内在动态。在给定的时间内,你可能由于以下几个原因而拥有一个微服务的多个实例:

  • 吞吐量(Throughput):根据传入的请求,你可能拥有更多或更少的微服务实例
  • 金丝雀发布
  • 蓝绿部署
  • A/B测试
简而言之,微服务到微服务的通信有特定的需求和问题需要解决。以下图片展示了这一方案:

该图示描述了几个技术挑战。显然,Microservice 1的主要职责是均衡所有Microservice 2实例之间的负载。因此,Microservice 1必须弄清楚我们在请求时刻有多少个Microservice 2实例。换句话说,Microservice 1必须实现服务发现和负载均衡。

另一方面,Microservice 2必须实现一些服务注册功能以告知Microservice 1何时有全新的实例。

想要拥有一个完全动态的环境,以下这些功能应该是微服务开发的一部分:

  • 流量控制:负载均衡的自然演变。我们想指定应该发送到每个Microservice 2实例的请求数量。 在Microservice 1和2之间加密通信
  • 借助断路器和健康检查以解决和克服网络问题
总而言之,主要问题是开发团队花费了大量资源编写十分复杂的代码,而这些代码与微服务预期交付的业务逻辑不直接相关。

有潜力的解决方案

如何将所有微服务都可以调用的外部标准化组件中的所有非功能和操作功能外部化?例如,下图编译了所有功能,这些功能不属于给定的微服务。因此,在确定所有功能之后,我们需要决定在哪里实现它们。

Solution #1 :将所有功能封装在一个library中

开发者将负责调用library提供的函数来解决微服务通信需求。

这个解决方案有几个缺点:

这是一个紧密耦合的解决方案,意味着微服务高度依赖于library 这个模式对于分布和升级新版本的library来说并不容易 这不符合微服务多语言的原则,因为这会将不同的编程语言应用于不同的上下文。

Solution #2:透明代理(Transparent Proxy)

这个解决方案实现了同样的功能集合。但是,采用了一种非常不同的方法:每个微服务都有一个特定的组件,扮演代理的角色,负责处理它的传入和传出流量。代理解决了我们之前描述的库的缺点,具体如下:

  • 代理是透明的,这意味着微服务不会意识到它正在附近运行并实现了与其他微服务进行通信所需的所有功能。
  • 由于它是一个透明的代理,开发者不需要改变代码来引用代理。因此,从微服务开发的角度来看,升级代理将是一个并不会对开发流程造成太大影响。
  • 代理可以使用微服务使用的不同技术和编程语言进行开发。
服务网格架构模式

虽然透明代理的方法给微服务开发团队和微服务通信需求带来了一些好处,但仍有一些缺失的部分:

  • 代理只是执行策略来实现通信需求,例如负载均衡、金丝雀发布等。
  • 由什么来负责定义这样的策略,并在所有运行的代理上发布呢?
解决方案架构需要另一个组件,这些组件将被管理员用来定义策略,它将负责向代理传播策略。

以下图片展示了最终架构,也就是服务网格模式:

如你所见,该模式包含了我们所描述的两个主要组件。

  • 数据平面:也被称为sidecar,它扮演着透明代理的角色。同样,每个微服务都会有自己的数据平面,拦截所有的入站和出站流量,并应用之前描述的策略。
  • 控制平面:由管理员用来定义策略并发布到数据平面。
一些重要的事情需要注意:

  • 这是一个 "push-based "的架构。数据平面不做 "调用 "来获取策略——那将会消耗网络。
  • 数据平面通常向控制平面或特定的基础设施报告使用指标。

手把手教你使用Rancher、Kong和Kong Mesh

Kong提供了一个企业级的综合服务连接平台,其包括了API gateway、Kubernetes ingress controller以及服务网格实现。该平台允许用户部署多个环境,如本地、混合云、多区域以及多云环境。

让我们借助运行在独立于云架构(cloud-agnostic)的Kubernetes集群上的金丝雀发布来实现服务网格,该集群可能包括GKE集群或任何其他的Kubernetes发行版。服务网格将由Kong Mesh实现,并由Kong for Kubernetes作为Kubernetes Ingress Controller。一般而言,ingress controller负责定义进入你的Kubernetes集群的入口点,暴露部署在其内部的微服务,并对其实行消费策略。

首先,确保你已经安装Rancher以及正在运行一个由Rancher管理的Kubernetes集群。在登录到Rancher之后,选在我们将要使用的Kubernetes集群,在本例中为“kong-rancher”。点击Cluster Explorer。你将会重定向到以下页面:

现在,让我们从服务网格开始:

1、 Kong Mesh Helm Chart

回到Rancher Cluster Manger主页并再次选择你的集群。点击菜单栏的“Tools”选项然后点击Catalogs,以创建一个新的catalog。点击Add Catalog按钮,将Kong Mesh的Helm chart收录其中(https://kong.github.io/kong-mesh-charts/)。

选择Global作为范围,Helm v3作为Helm版本。

现在点击Apps和Launch来查看在Catalog中可用的Kong Mesh。请注意,Kong作为Rancher的合作伙伴默认提供了Kong for Kubernetes的Helm chart:

2、 安装Kong Mesh

点击顶部菜单栏Namespaces选项并创建一个“kong-mesh-system”命名空间。

将鼠标移到kong-rancher顶部菜单选项上,点击kong-rancher活动集群。

点击Launch kubetcl

创建一个名为“license.json”的文件,用于存放你从Kong Mesh收到的license。格式如下:

{“license”: {“version”:1,“signature”:“6a7c81af4b0a42b380be25c2816a2bb1d761c0f906ae884f93eeca1fd16c8b5107cb6997c958f45d247078ca50a25399a5f87d546e59ea3be28284c3075a9769”,“payload”: {“customer”:“Kong_SE_Demo_H1FY22”,“license_creation_date”:“2020-11-30”,“product_subscription”:“Kong Enterprise Edition”,“support_plan”:“None”,“admin_seats”:“5”,“dataplanes”:“5”,“license_expiration_date”:“2021-06-30”,“license_key”:“XXXXXXXXXXXXX”}}} 现在使用以下命令创建一个Kubernetes通用密钥:

kubectl create secret generic kong-mesh-license -n kong-mesh-system --from-file=./license.json 关闭kubectl会话,点击Default项目以及顶部菜单栏的Apps。点击Launch按钮并选择kong-mesh Helm chart。

点击Use an existing namespace并选择我们刚刚创建的那个。这有几个参数(https://artifacthub.io/packages/helm/kong-mesh/kong-mesh)来配置Kong Mesh,但我们将保留所有默认值。点击Launch之后,你应该看到Kong Mesh应用程序部署完成。

你可以再次使用Rancher Cluster Explorer来检查安装。点击左侧菜单的Pods并选择kong-mesh-system的命名空间。

你也可以像这样使用kubectl:

NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75m fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75m kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16m kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76m kube-system fluentbit-gke-xqsdv 2/2 Running 0 76m kube-system gke-metrics-agent-gjrqr 1/1 Running 0 76m kube-system konnectivity-agent-4c4hf 1/1 Running 0 76m kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76m kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76m kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76m kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76m kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75m kube-system prometheus-to-sd-fdf9j 1/1 Running 0 76m kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 75m 3、 微服务部署

我们的Service Mesh部署是基于一个简单的微服务到微服务的通信场景。由于我们运行的是金丝雀发布,被调用的微服务有两个版本:

“magnanimo”:通过Kong暴露Kubernetes ingress controller。 “benigno”:提供了一个 “hello” endpoint,在这个端点中,它呼应了当前的datetime。它有一个金丝雀发布,会发送一个稍微不同的响应。

下图展示了这一架构:

创建一个带有sidecar注入注释的命名空间。你可以再次使用Rancher Cluster Manager:选择你的集群,然后单击Projects/Namespaces。点击Add Namespace。输入 “kong-mesh-app” 作为名称,并包含一个带有 “kuma.io/sidecar-injection” 键和 “enabled” 作为其值的注释。

当然,你也可以选择使用kubectl

kubectl create namespace kong-mesh-app kubectl annotate namespace kong-mesh-app kuma.io/sidecar-injection=enabled Submit the following declaration to deploy Magnanimo injecting the Kong Mesh data plane cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: magnanimo namespace: kong-mesh-app spec: replicas: 1 selector: matchLabels: app: magnanimo template: metadata: labels: app: magnanimo spec: containers: - name: magnanimo image: claudioacquaviva/magnanimo ports: - containerPort: 4000 --- apiVersion: v1 kind: Service metadata: name: magnanimo namespace: kong-mesh-app labels: app: magnanimo spec: type: ClusterIP ports: - port: 4000 name: http selector: app: magnanimo EOF 使用Rancher Cluster Manager检查你的部署。将鼠标移动至kong-rancher菜单上,点击Default项目,可以看到当前的部署情况:

点击magnanimo检查部署的细节,包括其pods:

点击magnanimo pod,检查其内部运行的容器。

我们可以看到,pod有两个运行的容器:

  • magnanimo:微服务实际运行的地方。
  • kuma-sidecar:在部署的时候注入,作为Kong Mesh的数据平面。
同理,部署Benigno的时候,也有自己的sidecar:

cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: benigno-v1 namespace: kong-mesh-app spec: replicas: 1 selector: matchLabels: app: benigno template: metadata: labels: app: benigno version: v1 spec: containers: - name: benigno image: claudioacquaviva/benigno ports: - containerPort: 5000 --- apiVersion: v1 kind: Service metadata: name: benigno namespace: kong-mesh-app labels: app: benigno spec: type: ClusterIP ports: - port: 5000 name: http selector: app: benigno EOF And finally, deploy Benigno canary release. Notice that the canary release will be abstracted by the same Benigno Kubernetes Service created before: cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: benigno-v2 namespace: kong-mesh-app spec: replicas: 1 selector: matchLabels: app: benigno template: metadata: labels: app: benigno version: v2 spec: containers: - name: benigno image: claudioacquaviva/benigno\_rc ports: - containerPort: 5000 EOF 使用以下命令检查部署和Pods:

$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75m fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75m kong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 110s kong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 30s kong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 5m3s kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16m kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76m kube-system fluentbit-gke-xqsdv 2/2 Running 0 76m kube-system gke-metrics-agent-gjrqr 1/1 Running 0 76m kube-system konnectivity-agent-4c4hf 1/1 Running 0 76m kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76m kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76m kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76m kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76m kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75m kube-system prometheus-to-sd-fdf9j 1/1 Running 0 76m kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 75m $ kubectl get service --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 79m kong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 4m6s kong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 7m18s kong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 18m kube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 79m kube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 79m kube-system metrics-server ClusterIP 10.0.20.174 <none> 443/TCP 79m 你也可以使用Kong Mesh控制台来检查微服务和数据平面。在Terminal上运行以下命令:

kubectl port-forward service/kuma-control-plane -n kong-mesh-system 5681 重定向你的浏览器到http://localhost:5681/gui。点击Skip to Dashboard和All Data Plane Proxies:

启动一个循环,看看金丝雀发布的运行情况。注意服务已经被部署为ClusterIP类型,所以你需要用 “port-forward”直接暴露它们。下一步将展示如何用Ingress Controller暴露服务。

在本地terminal上运行:

kubectl port-forward service/magnanimo -n kong-mesh-app 4000 打开另一个Terminal,开始循环。请求要到Magnanimo提供的4000端口。路径“/hw2 ”将请求路由到Benigno服务,它后面有两个endpoint,与Benigno两个版本有关:

while [1]; do curl http://localhost:4000/hw2; echo; done 你应该看到类似下方的结果:

Hello World, Benigno: 2020-11-20 12:57:05.811667 Hello World, Benigno: 2020-11-20 12:57:06.304731 Hello World, Benigno, Canary Release: 2020-11-20 12:57:06.789208 Hello World, Benigno: 2020-11-20 12:57:07.269674 Hello World, Benigno, Canary Release: 2020-11-20 12:57:07.755884 Hello World, Benigno, Canary Release: 2020-11-20 12:57:08.240453 Hello World, Benigno: 2020-11-20 12:57:08.728465 Hello World, Benigno: 2020-11-20 12:57:09.208588 Hello World, Benigno, Canary Release: 2020-11-20 12:57:09.689478 Hello World, Benigno, Canary Release: 2020-11-20 12:57:10.179551 Hello World, Benigno: 2020-11-20 12:57:10.662465 Hello World, Benigno: 2020-11-20 12:57:11.145237 Hello World, Benigno, Canary Release: 2020-11-20 12:57:11.618557 Hello World, Benigno: 2020-11-20 12:57:12.108586 Hello World, Benigno, Canary Release: 2020-11-20 12:57:12.596296 Hello World, Benigno, Canary Release: 2020-11-20 12:57:13.093329 Hello World, Benigno: 2020-11-20 12:57:13.593487 Hello World, Benigno, Canary Release: 2020-11-20 12:57:14.068870 4、 控制金丝雀发布的成本

正如我们所见,两个Benigno微服务发布的请求使用了循环策略。也就是说,我们无法控制金丝雀发布的花销。Service Mesh允许我们定义何时以及如何将金丝雀发布暴露给我们的consumer(在本例中指Magnanimo微服务)。

要定义一个策略来控制流向两个版本的流量,需要使用下面这个声明。它说90%的流量应该流向当前版本,而只有10%的流量应该重定向到金丝雀发布。

cat <<EOF | kubectl apply -f - apiVersion: kuma.io/v1alpha1 kind: TrafficRoute mesh: default metadata: namespace: default name: route-1 spec: sources: - match: kuma.io/service: magnanimo\_kong-mesh-app\_svc\_4000 destinations: - match: kuma.io/service: benigno\_kong-mesh-app\_svc\_5000 conf: split: - weight: 90 destination: kuma.io/service: benigno\_kong-mesh-app\_svc\_5000 version: v1 - weight: 10 destination: kuma.io/service: benigno\_kong-mesh-app\_svc\_5000 version: v2 EOF 应用声明之后,你应该看到如下结果:

Hello World, Benigno: 2020-11-20 13:05:02.553389 Hello World, Benigno: 2020-11-20 13:05:03.041120 Hello World, Benigno: 2020-11-20 13:05:03.532701 Hello World, Benigno: 2020-11-20 13:05:04.021804 Hello World, Benigno: 2020-11-20 13:05:04.515245 Hello World, Benigno, Canary Release: 2020-11-20 13:05:05.000644 Hello World, Benigno: 2020-11-20 13:05:05.482606 Hello World, Benigno: 2020-11-20 13:05:05.963663 Hello World, Benigno, Canary Release: 2020-11-20 13:05:06.446599 Hello World, Benigno: 2020-11-20 13:05:06.926737 Hello World, Benigno: 2020-11-20 13:05:07.410605 Hello World, Benigno: 2020-11-20 13:05:07.890827 Hello World, Benigno: 2020-11-20 13:05:08.374686 Hello World, Benigno: 2020-11-20 13:05:08.857266 Hello World, Benigno: 2020-11-20 13:05:09.337360 Hello World, Benigno: 2020-11-20 13:05:09.816912 Hello World, Benigno: 2020-11-20 13:05:10.301863 Hello World, Benigno: 2020-11-20 13:05:10.782395 Hello World, Benigno: 2020-11-20 13:05:11.262624 Hello World, Benigno: 2020-11-20 13:05:11.743427 Hello World, Benigno: 2020-11-20 13:05:12.221174 Hello World, Benigno: 2020-11-20 13:05:12.705731 Hello World, Benigno: 2020-11-20 13:05:13.196664 Hello World, Benigno: 2020-11-20 13:05:13.680319 5、 安装Kong for Kubernetes

让我们回到Rancher中安装我们的Kong for Kubernetes Ingress Controller,并控制服务网格的暴露。在Rancher Catalog页面中,点击Kong图标。接受默认值,然后点击Launch:

你应该看到Kong和Kong Mesh这两个应用程序都已经部署完成:

再次使用kubectl检查安装:

$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 84m fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 83m kong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 10m kong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 8m47s kong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 13m kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 24m kong kong-kong-754cd6947-db2j9 2/2 Running 1 72s kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 85m kube-system fluentbit-gke-xqsdv 2/2 Running 0 84m kube-system gke-metrics-agent-gjrqr 1/1 Running 0 84m kube-system konnectivity-agent-4c4hf 1/1 Running 0 84m kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 84m kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 84m kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 84m kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 85m kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 84m kube-system prometheus-to-sd-fdf9j 1/1 Running 0 84m kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 84m $ kubectl get service --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 85m kong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 10m kong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 13m kong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 24m kong kong-kong-proxy LoadBalancer 10.0.26.38 35.222.91.194 80:31867/TCP,443:31039/TCP 78s kube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 85m kube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 85m kube-system metrics-server ClusterIP 10.0.20.174 <none> 443/TCP 85m 6、 创建Ingress

通过下面的声明,我们将通过一个Ingress和它的路由 “/route1” 来暴露Magnanimo微服务。

cat <<EOF | kubectl apply -f - apiVersion: extensions/v1beta1 kind: Ingress metadata: name: route1 namespace: kong-mesh-app annotations: konghq.com/strip-path: "true" spec: rules: - http: paths: - path: /route1 backend: serviceName: magnanimo servicePort: 4000 EOF 现在,临时的 “port-forward” 暴露机制可以被正式的Ingress所取代。而我们的循环也可以开始消耗Ingress,结果如下:

while [1]; do curl http://35.222.91.194/route1/hw2; echo; done

有关详细教程丨如何利用Rancher和Kong实现服务网格?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  8. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  9. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐