使用 Flomesh 强化 Spring Cloud 服务治理

c4a64d753ee25fb7b595434a86e18a56.gif

作者 | Addo Zhang

来源 | 云原生指北

写在最前

这篇是关于如何使用 Flomesh[1] 服务网格来强化 Spring Cloud 的服务治理能力,降低 Spring Cloud 微服务架构落地服务网格的门槛,实现“自主可控”。


架构

dfd7428ab957bca03c5cafa0d71b6555.png
Architect

环境搭建

搭建 Kubernetes 环境,可以选择 kubeadm 进行集群搭建。也可以选择 minikube、k3s、Kind 等,本文使用 k3s。

使用 k3d[3] 安装 k3s[4]。k3d 将在 Docker 容器中运行 k3s,因此需要保证已经安装了 Docker。

$ k3d cluster create spring-demo -p "81:80@loadbalancer"--k3s-server-arg '--no-deploy=traefik'

安装 Flomesh

从仓库 https://github.com/flomesh-io/flomesh-bookinfo-demo.git 克隆代码。进入到 flomesh-bookinfo-demo/kubernetes目录。

所有 Flomesh 组件以及用于 demo 的 yamls 文件都位于这个目录中。

安装 Cert Manager

$ kubectl apply -f artifacts/cert-manager-v1.3.1.yaml
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created
namespace/cert-manager created
serviceaccount/cert-manager-cainjector created
serviceaccount/cert-manager created
serviceaccount/cert-manager-webhook created
clusterrole.rbac.authorization.k8s.io/cert-manager-cainjector created
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-issuers created
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers created
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificates created
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-orders created
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-challenges created
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim created
clusterrole.rbac.authorization.k8s.io/cert-manager-view created
clusterrole.rbac.authorization.k8s.io/cert-manager-edit created
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io created
clusterrole.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-issuers created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificates created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-orders created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-challenges created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io created
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews created
role.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection created
role.rbac.authorization.k8s.io/cert-manager:leaderelection created
role.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving created
rolebinding.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection created
rolebinding.rbac.authorization.k8s.io/cert-manager:leaderelection created
rolebinding.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving created
service/cert-manager created
service/cert-manager-webhook created
deployment.apps/cert-manager-cainjector created
deployment.apps/cert-manager created
deployment.apps/cert-manager-webhook created
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

注意: 要保证 cert-manager 命名空间中所有的 pod 都正常运行:

$ kubectl get pod -n cert-manager
NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-webhook-56fdcbb848-q7fn5      1/1Running098s
cert-manager-59f6c76f4b-z5lgf              1/1Running098s
cert-manager-cainjector-59f76f7fff-flrr7   1/1Running098s

安装 Pipy Operator

$ kubectl apply -f artifacts/pipy-operator.yaml

执行完命令后会看到类似的结果:

namespace/flomesh created
customresourcedefinition.apiextensions.k8s.io/proxies.flomesh.io created
customresourcedefinition.apiextensions.k8s.io/proxyprofiles.flomesh.io created
serviceaccount/operator-manager created
role.rbac.authorization.k8s.io/leader-election-role created
clusterrole.rbac.authorization.k8s.io/manager-role created
clusterrole.rbac.authorization.k8s.io/metrics-reader created
clusterrole.rbac.authorization.k8s.io/proxy-role created
rolebinding.rbac.authorization.k8s.io/leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/manager-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/proxy-rolebinding created
configmap/manager-config created
service/operator-manager-metrics-service created
service/proxy-injector-svc created
service/webhook-service created
deployment.apps/operator-manager created
deployment.apps/proxy-injector created
certificate.cert-manager.io/serving-cert created
issuer.cert-manager.io/selfsigned-issuer created
mutatingwebhookconfiguration.admissionregistration.k8s.io/mutating-webhook-configuration created
mutatingwebhookconfiguration.admissionregistration.k8s.io/proxy-injector-webhook-cfg created
validatingwebhookconfiguration.admissionregistration.k8s.io/validating-webhook-configuration created

注意:要保证 flomesh 命名空间中所有的 pod 都正常运行:

$ kubectl get pod -n flomesh
NAME                               READY   STATUS    RESTARTS   AGE
proxy-injector-5bccc96595-spl6h    1/1Running039s
operator-manager-c78bf8d5f-wqgb4   1/1Running039s

安装 Ingress 控制器:ingress-pipy

$ kubectl apply -f ingress/ingress-pipy.yaml
namespace/ingress-pipy created
customresourcedefinition.apiextensions.k8s.io/ingressparameters.flomesh.io created
serviceaccount/ingress-pipy created
role.rbac.authorization.k8s.io/ingress-pipy-leader-election-role created
clusterrole.rbac.authorization.k8s.io/ingress-pipy-role created
rolebinding.rbac.authorization.k8s.io/ingress-pipy-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/ingress-pipy-rolebinding created
configmap/ingress-config created
service/ingress-pipy-cfg created
service/ingress-pipy-controller created
service/ingress-pipy-defaultbackend created
service/webhook-service created
deployment.apps/ingress-pipy-cfg created
deployment.apps/ingress-pipy-controller created
deployment.apps/ingress-pipy-manager created
certificate.cert-manager.io/serving-cert created
issuer.cert-manager.io/selfsigned-issuer created
mutatingwebhookconfiguration.admissionregistration.k8s.io/mutating-webhook-configuration configured
validatingwebhookconfiguration.admissionregistration.k8s.io/validating-webhook-configuration configured

检查 ingress-pipy 命名空间下 pod 的状态:

$ kubectl get pod -n ingress-pipy
NAME                                       READY   STATUS    RESTARTS   AGE
svclb-ingress-pipy-controller-8pk8k1/1Running071s
ingress-pipy-cfg-6bc649cfc7-8njk71/1Running071s
ingress-pipy-controller-76cd866d78-m7gfp   1/1Running071s
ingress-pipy-manager-5f568ff988-tw5w6      0/1Running070s

至此,你已经成功安装 Flomesh 的所有组件,包括 operator 和 ingress 控制器。

中间件

Demo 需要用到中间件完成日志和统计数据的存储,这里为了方便使用 pipy 进行 mock:直接在控制台中打印数据。

另外,服务治理相关的配置有 mock 的 pipy config 服务提供。

log & metrics

$ cat > middleware.js <<EOF
pipy()
.listen(8123)
.link('mock')
.listen(9001)
.link('mock')
.pipeline('mock')
.decodeHttpRequest()
.replaceMessage(req =>(console.log(req.body.toString()),
newMessage('OK')
)
)
.encodeHttpResponse()
EOF
$ docker run --rm --name middleware --entrypoint "pipy"-v ${PWD}:/script -p 8123:8123-p 9001:9001 flomesh/pipy-pjs:0.4.0-118/script/middleware.js

pipy config

$ cat > mock-config.json <<EOF
{
"ingress":{},
"inbound":{
"rateLimit":-1,
"dataLimit":-1,
"circuitBreak":false,
"blacklist":[]
},
"outbound":{
"rateLimit":-1,
"dataLimit":-1
}
}
EOF
$ cat > mock.js <<EOF
pipy({_CONFIG_FILENAME:'mock-config.json',_serveFile:(req, filename, type)=>(
newMessage(
{bodiless: req.head.method ==='HEAD',headers:{
'etag': os.stat(filename)?.mtime |0,
'content-type': type,
},
},req.head.method ==='HEAD'?null: os.readFile(filename),
)
),_router:new algo.URLRouter({
'/config': req => _serveFile(req, _CONFIG_FILENAME,'application/json'),
'/*':()=>newMessage({ status:404},'Not found'),
}),
})
// Config
.listen(9000)
.decodeHttpRequest()
.replaceMessage(req =>(_router.find(req.head.path)(req)
)
)
.encodeHttpResponse()
EOF
$ docker run --rm --name mock --entrypoint "pipy"-v ${PWD}:/script -p 9000:9000 flomesh/pipy-pjs:0.4.0-118/script/mock.js

运行 Demo

Demo 运行在另一个独立的命名空间 flomesh-spring 中,执行命令 kubectl apply -f base/namespace.yaml 来创建该命名空间。如果你 describe 该命名空间你会发现其使用了 flomesh.io/inject=true 标签。

这个标签告知 operator 的 admission webHook 拦截标注的命名空间下 pod 的创建。

$ kubectl describe ns flomesh-spring
Name:         flomesh-spring
Labels:       app.kubernetes.io/name=spring-meshapp.kubernetes.io/version=1.19.0flomesh.io/inject=truekubernetes.io/metadata.name=flomesh-spring
Annotations:<none>
Status:Active
No resource quota.
NoLimitRange resource.

我们首先看下 Flomesh 提供的 CRD ProxyProfile。这个 demo 中,其定义了 sidecar 容器片段以及所使用的的脚本。检查 sidecar/proxy-profile.yaml 获取更多信息。执行下面的命令,创建 CRD 资源。

$ kubectl apply -f sidecar/proxy-profile.yaml

检查是否创建成功:

$ kubectl get pf -o wide
NAME                         NAMESPACE        DISABLED   SELECTOR                                     CONFIG                                                                AGE
proxy-profile-002-bookinfo   flomesh-spring   false{"matchLabels":{"sys":"bookinfo-samples"}}{"flomesh-spring":"proxy-profile-002-bookinfo-fsmcm-b67a9e39-0418"}27s

As the services has startup dependencies, you need to deploy it one by one following the strict order. Before starting, check the Endpoints section of base/clickhouse.yaml.

提供中间件的访问 endpoid,将 base/clickhouse.yamlbase/metrics.yaml 和 base/config.yaml 中的 ip 地址改为本机的 ip 地址(不是 127.0.0.1)。

修改之后,执行如下命令:

$ kubectl apply -f base/clickhouse.yaml
$ kubectl apply -f base/metrics.yaml
$ kubectl apply -f base/config.yaml
$ kubectl get endpoints samples-clickhouse samples-metrics samples-config
NAME                 ENDPOINTS            AGE
samples-clickhouse   192.168.1.101:81233m
samples-metrics      192.168.1.101:90013s
samples-config       192.168.1.101:90003m

部署注册中心

$ kubectl apply -f base/discovery-server.yaml

检查注册中心 pod 的状态,确保 3 个容器都运行正常。

$ kubectl get pod
NAME                                           READY   STATUS        RESTARTS   AGE
samples-discovery-server-v1-85798c47d4-dr72k   3/3Running096s

部署配置中心

$ kubectl apply -f base/config-service.yaml

部署 API 网关以及 bookinfo 相关的服务

$ kubectl apply -f base/bookinfo-v1.yaml
$ kubectl apply -f base/bookinfo-v2.yaml
$ kubectl apply -f base/productpage-v1.yaml
$ kubectl apply -f base/productpage-v2.yaml

检查 pod 状态,可以看到所有 pod 都注入了容器。

$ kubectl get pods
samples-discovery-server-v1-85798c47d4-p6zpb       3/3Running019h
samples-config-service-v1-84888bfb5b-8bcw91/1Running019h
samples-api-gateway-v1-75bb6456d6-nt2nl            3/3Running06h43m
samples-bookinfo-ratings-v1-6d557dd894-cbrv7       3/3Running06h43m
samples-bookinfo-details-v1-756bb89448-dxk66       3/3Running06h43m
samples-bookinfo-reviews-v1-7778cdb45b-pbknp       3/3Running06h43m
samples-api-gateway-v2-7ddb5d7fd9-8jgms3/3Running06h37m
samples-bookinfo-ratings-v2-845d95fb7-txcxs        3/3Running06h37m
samples-bookinfo-reviews-v2-79b4c67b77-ddkm2       3/3Running06h37m
samples-bookinfo-details-v2-7dfb4d7c-jfq4j         3/3Running06h37m
samples-bookinfo-productpage-v1-854675b56-8n2xd1/1Running07m1s
samples-bookinfo-productpage-v2-669bd8d9c7-8wxsf1/1Running06m57s

添加 Ingress 规则

执行如下命令添加 Ingress 规则。

$ kubectl apply -f ingress/ingress.yaml

测试前的准备

访问 demo 服务都要通过 ingress 控制器。因此需要先获取 LB 的 ip 地址。

//Obtain the controller IP
//Here, we append port. 
ingressAddr=`kubectl get svc ingress-pipy-controller -n ingress-pipy -o jsonpath='{.spec.clusterIP}'`:81

这里我们使用了是 k3d 创建的 k3s,命令中加入了 -p 81:80@loadbalancer 选项。我们可以使用 127.0.0.1:81 来访问 ingress 控制器。这里执行命令 ingressAddr=127.0.0.1:81

Ingress 规则中,我们为每个规则指定了 host,因此每个请求中需要通过 HTTP 请求头 Host 提供对应的 host

或者在 /etc/hosts 添加记录:

$ kubectl get ing ingress-pipy-bookinfo -n flomesh-spring -o jsonpath="{range .spec.rules[*]}{.host}{'\n'}"
api-v1.flomesh.cn
api-v2.flomesh.cn
fe-v1.flomesh.cn
fe-v2.flomesh.cn
//添加记录到 /etc/hosts
127.0.0.1 api-v1.flomesh.cn api-v2.flomesh.cn fe-v1.flomesh.cn fe-v2.flomesh.cn

验证

$ curl http://127.0.0.1:81/actuator/health -H 'Host: api-v1.flomesh.cn'
{"status":"UP","groups":["liveness","readiness"]}
//OR
$ curl http://api-v1.flomesh.cn:81/actuator/health
{"status":"UP","groups":["liveness","readiness"]}

测试

灰度

在 v1 版本的服务中,我们为 book 添加 rating 和 review。

# rate a book
$ curl -X POST http://$ingressAddr/bookinfo-ratings/ratings \
-H "Content-Type: application/json" \
-H "Host: api-v1.flomesh.cn" \
-d '{"reviewerId":"9bc908be-0717-4eab-bb51-ea14f669ef20","productId":"2099a055-1e21-46ef-825e-9e0de93554ea","rating":3}'
$ curl http://$ingressAddr/bookinfo-ratings/ratings/2099a055-1e21-46ef-825e-9e0de93554ea -H "Host: api-v1.flomesh.cn"
# review a book
$ curl -X POST http://$ingressAddr/bookinfo-reviews/reviews \
-H "Content-Type: application/json" \
-H "Host: api-v1.flomesh.cn" \
-d '{"reviewerId":"9bc908be-0717-4eab-bb51-ea14f669ef20","productId":"2099a055-1e21-46ef-825e-9e0de93554ea","review":"This was OK.","rating":3}'
$ curl http://$ingressAddr/bookinfo-reviews/reviews/2099a055-1e21-46ef-825e-9e0de93554ea -H "Host: api-v1.flomesh.cn"

执行上面的命令之后,我们可以在浏览器中访问前端服务(http://fe-v1.flomesh.cn:81/productpage?u=normal、 http://fe-v2.flomesh.cn:81/productpage?u=normal),只有 v1 版本的前端中才能看到刚才添加的记录。

c7d25107f7c53c21874a3cffaec5e82a.png
v1
fb4f3ff403f37bbc33b661695c402308.png
v2

熔断

这里熔断我们通过修改 mock-config.json 中的 inbound.circuitBreak 为 true,来将服务强制开启熔断:

{
"ingress":{},
"inbound":{
"rateLimit":-1,
"dataLimit":-1,
"circuitBreak":true,//here
"blacklist":[]
},
"outbound":{
"rateLimit":-1,
"dataLimit":-1
}
}
$ curl http://$ingressAddr/actuator/health -H 'Host: api-v1.flomesh.cn'
HTTP/1.1503ServiceUnavailable
Connection: keep-alive
Content-Length:27
ServiceCircuitBreakOpen

限流

修改 pipy config 的配置,将 inbound.rateLimit 设置为 1。

{
"ingress":{},
"inbound":{
"rateLimit":1,//here
"dataLimit":-1,
"circuitBreak":false,
"blacklist":[]
},
"outbound":{
"rateLimit":-1,
"dataLimit":-1
}
}

我们使用 wrk 模拟发送请求,20 个连接、20 个请求、持续 30s:

$ wrk -t20 -c20 -d30s --latency http://$ingressAddr/actuator/health -H 'Host: api-v1.flomesh.cn'
Running30s test @ http://127.0.0.1:81/actuator/health
20 threads and20 connections
ThreadStatsAvgStdevMax+/-Stdev
Latency951.51ms206.23ms1.04s93.55%
Req/Sec0.611.7110.0093.55%
LatencyDistribution
50%1.00s
75%1.01s
90%1.02s
99%1.03s
620 requests in30.10s,141.07KB read
Requests/sec:20.60
Transfer/sec:4.69KB

从结果来看 20.60 req/s,即每个连接 1 req/s。

黑白名单

将 pipy config 的 mock-config.json 做如下修改:ip 地址使用的是 ingress controller 的 pod ip。

$ kgpo -n ingress-pipy ingress-pipy-controller-76cd866d78-4cqqn-o jsonpath='{.status.podIP}'
10.42.0.78
{
"ingress":{},
"inbound":{
"rateLimit":-1,
"dataLimit":-1,
"circuitBreak":false,
"blacklist":["10.42.0.78"]//here
},
"outbound":{
"rateLimit":-1,
"dataLimit":-1
}
}

还是访问网关的接口

curl http://$ingressAddr/actuator/health -H 'Host: api-v1.flomesh.cn'
HTTP/1.1503ServiceUnavailable
content-type: text/plain
Connection: keep-alive
Content-Length:20
ServiceUnavailable

引用链接

[1] Flomesh: https://flomesh.cn/
[2] github: https://github.com/flomesh-io/flomesh-bookinfo-demo
[3] k3d: https://k3d.io/
[4] k3s: https://github.com/k3s-io/k3s

97538ef7637ec2dca76b556ed4ce3529.gif

82c7cd52e6538a9bc7b5d8fee4a5992c.png

往期推荐

虚幻引擎5上的《黑客帝国》全新体验,爱了爱了

元宇宙真的是割韭菜吗?

Log4j 第三次发布漏洞补丁,漏洞或将长存

核弹级漏洞,把log4j扒给你看!

c33cf76b4bc93f382276bb00a7d06008.gif

点分享

d58245cc44d89faab0dea743f7b5d81b.gif

点收藏

80932cecbbaa0bd0cd1efbc32c5c14a5.gif

点点赞

4cffe852cba005ae8173d89a7147e258.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何避免JS内存泄漏?

简介&#xff1a; 很多开发者可能平时并不关心自己维护的页面是否存在内存泄漏&#xff0c;原因可能是刚开始简单的页面内存泄漏的速度很缓慢&#xff0c;在造成严重卡顿之前可能就被用户刷新了&#xff0c;问题也就被隐藏了&#xff0c;但是随着页面越来越复杂&#xff0c;尤其…

java传递实例_Java方法的参数传递机制实例详解

本文实例讲述了Java方法的参数传递机制。分享给大家供大家参考&#xff0c;具体如下&#xff1a;参数传递机制对于程序设计语言来说&#xff0c;一般方法(函数)的参数传递有两种&#xff1a;按值传递和按引用传递。按值传递意味着当将一个参数传递给一个方法时&#xff0c;方法…

低代码发展专访系列之六:低代码平台能解决业务重构的问题么?

编辑 | 曹芊芊 话题&#xff1a;低代码发展系列专访 前言&#xff1a;2019年开始&#xff0c;低代码爆火。有人认为它是第四代编程语言&#xff0c;有人认为它是开发模式的颠覆&#xff0c;也有人认为是企业管理模式的变革……有很多声音&#xff0c;社区讨论很热烈。CSDN随后展…

在 Dubbo3.0 上服务治理的实践

简介&#xff1a; Dubbo 3.0 是在云原生背景下诞生的&#xff0c;使用 Dubbo 构建的微服务遵循云原生思想&#xff0c;能更好的复用底层云原生基础设施、贴合云原生微服务架构。 Dubbo3.0 介绍 作者 | 十眠 自从 Apache Dubbo 在 2011 年开源以来&#xff0c;经过多年一众大…

redis 可视化工具_自荐一个有情怀的跨平台Redis可视化客户端工具——RedisViewer...

介绍在以往的文章中曾经介绍过几款Redis的可视化工具&#xff0c;在笔者的印象中&#xff0c;Redis至今没有一款非常专业的可视化管理客户端&#xff0c;就算之前介绍过的几款也是差强人意&#xff0c;有些时候满足不了我们的需求&#xff0c;而今天本文要介绍的是另一款值得推…

内核热补丁,真的安全么?

简介&#xff1a; Linux 内核函数的热替换“撞上”函数调用约定还靠谱吗&#xff1f; Linux 内核热补丁可以修复正在运行的 linux 内核&#xff0c;是一种维持线上稳定性不可缺少的措施&#xff0c;现在比较常见的比如 kpatch 和 livepatch。内核热补丁可以修复内核中正在运行的…

谁是 2021「IT 圈」年度 C 位?快来报名,彰显你的影响力!

2021年&#xff0c;数字化转型正磅礴兴起&#xff0c;大批传统企业正在拥抱数字化&#xff0c;云计算、大数据、AI、5G应用能力正在变成企业的核心竞争力&#xff1b;核心技术正在崛起&#xff0c;在操作系统、数据库&#xff0c;依靠开源的力量&#xff0c;众多开发者背后的行…

当Java遇上机密计算,又一段奇幻之旅开始了!

简介&#xff1a; 汪少军&#xff1a;如何为Java业务提供机密计算保护&#xff1f; 写在前面 在信息世界里&#xff0c;数据存在三种状态&#xff1a; 存储态、传输态和计算态。存储在数据库或磁盘中的数据属于存储状态&#xff0c;在网络中传输的数据属于传输状态&#xff0c…

电脑桌面归纳小窗口_电脑一分钟小技巧:如何将电脑设置为定时关机?

关注公众号&#xff0c;发现好教程如何设置电脑设置定时关机呢&#xff1f;哈哈哈&#xff0c;可能这个教程用处不大&#xff0c;不过每个教程都有它的用处&#xff0c;这个也算是教程哈&#xff01;有些小伙伴可能需要这个教程&#xff01;至于什么用处&#xff0c;我就不多说…

时序数据库永远的难关 — 时间线膨胀(高基数 Cardinality)问题的解决方案

简介&#xff1a; 本文主要讨论 influxdb 在遇到写入的数据出现高基数 Cardinality 问题时&#xff0c;一些可行的解决方案。 作者 | 徐建伟 &#xff08;竹影&#xff09; 前序 随着移动端发展走向饱和&#xff0c;现在整个 IT 行业都期待着“万物互联”的物联网时代。在物…

中文巨量模型“源1.0”:模型结构与生成效果解析

浪潮人工智能研究院 “源 1.0”自 2021 年 9 月底发布以来收获了广泛的关注。其参数量达 2457 亿&#xff0c;超越美国 OpenAI 组织研发的 GPT-3。“源 1.0”在语言智能方面表现优异&#xff0c;获得中文语言理解评测基准 CLUE 榜单的零样本学习&#xff08;zero-shot&#xff…

python中gmtime的hour错误_python中gmtime的hour错误_在Python中操作日期和时间之gmtime()方法的使用...

python中datetime怎么用广告总是在最精彩的时候出现&#xff0c;你总是在小编爱的最深的时候离开。 日期相关的操作 from datetime import datetime from datetime import timedelta DATE_FMT %Y-%m-%d DATETIME_FMT %Y-%m-%d %H:%M:%S DATE_US_FMT %d/%m/%Y 格式化常用的…

webview键盘自适应_黑爵毛茸茸机械键盘:感受来自治愈系的暖萌

随着近几年电竞业的火爆&#xff0c;特别是女性玩家的增多&#xff0c;越来越多的外设厂商推出了个性化定制的产品&#xff0c;比如符合女生群体的鼠标、键盘、显卡甚至主板等。今天为大家介绍的这款黑爵毛茸茸机械键盘&#xff0c;是黑爵Project C系列的第三款主题键盘&#x…

阿里云云效技术专家分享:云原生开发、调测及可靠发布解决方案

简介&#xff1a; 高效开发、稳健发布。 在云原生环境中&#xff0c;基于Kubernetes的工具链一方面简化了开发者的许多日常琐碎&#xff0c;另一方面也带来了许多新的概念和工作方式的改变。本篇文章将聚焦于云原生基础设施&#xff0c;谈谈如何在面向云原生的开发流程中&…

代码质量第 5 层 - 只是实现了功能

产品实现的功能是产品价值的体现形式。功能实现是基础。功能没有实现&#xff0c;其他方面做得再好也没有意义。那么&#xff0c;如何保证实现的功能覆盖了需求呢&#xff1f; 产品实现的功能是产品价值的体现形式。功能实现是基础。功能没有实现&#xff0c;其他方面做得再好也…

阿里巴巴 DevOps 工具体系

简介&#xff1a; 随着阿里巴巴多元化业务 20 多年的高速发展&#xff0c;技术体系经历了 web 时代、移动化时代、数据智能时代、云计算时代等多个重大变革。在这些变革中&#xff0c;开发者面对的技术体系、工具体系、知识体系也在不断进化。研发工具在其中起到了技术规模化和…

云原生引领全云开发时代

简介&#xff1a; 云原生是近几年最火爆的技术热词之一&#xff0c;几乎所有的云计算产品都会或多或少跟云原生发生关联&#xff0c;云原生正在重塑整个软件的生命周期。但到底什么是云原生&#xff1f;云原生带来的最大的技术创新和未来机会是什么&#xff1f;以及&#xff0c…

中国首部智能交通微纪录片正式发布 探讨交通强国高质量发展路径

12月23日&#xff0c;由央视财经出品&#xff0c;中国首部智能交通题材微纪录片《大国交通-车路智行》正式发布。该微纪录片全景式呈现出中国交通领域智能化转型历程&#xff0c;探索了交通强国高质量发展的中国路径。据悉&#xff0c;《大国交通-车路智行》微纪录片共五集&…

Kettle on MaxCompute使用指南

简介&#xff1a; Kettle是一款开源的ETL工具&#xff0c;纯java实现&#xff0c;可以运行于Windows, Unix, Linux上运行&#xff0c;提供图形化的操作界面&#xff0c;可以通过拖拽控件的方式&#xff0c;方便地定义数据传输的拓扑。Kettle支持丰富的数据输入输出源&#xff0…

使用AirFlow调度MaxCompute

简介&#xff1a; airflow是Airbnb开源的一个用python编写的调度工具&#xff0c;基于有向无环图(DAG)&#xff0c;airflow可以定义一组有依赖的任务&#xff0c;按照依赖依次执行&#xff0c;通过python代码定义子任务&#xff0c;并支持各种Operate操作器&#xff0c;灵活性大…