自动缩放Kubernetes上的Kinesis Data Streams应用程序

想要学习如何在Kubernetes上自动缩放您的Kinesis Data Streams消费者应用程序,以便节省成本并提高资源效率吗?本文提供了一个逐步指南,教您如何实现这一目标。

通过利用Kubernetes对Kinesis消费者应用程序进行自动缩放,您可以从其内置功能中受益,例如水平Pod自动缩放器(Horizontal Pod Autoscaler)。


什么是Amazon Kinesis和Kinesis Data Streams? 

Amazon Kinesis是一个用于实时数据处理、摄取和分析的平台。Kinesis Data Streams是一个无服务器的流式数据服务(属于Kinesis流式数据平台的一部分),还包括Kinesis Data Firehose、Kinesis Video Streams和Kinesis Data Analytics。

Kinesis Data Streams可以弹性地扩展,并持续适应数据摄取速率和流消费速率的变化。它可用于构建实时数据分析应用程序、实时仪表板和实时数据管道。

让我们首先概述一些Kinesis Data Streams的关键概念。


Kinesis Data Streams:高级架构 

  • Kinesis数据流由一组分片组成。每个分片包含一系列数据记录。 

  • 生产者持续将数据推送到Kinesis Data Streams,消费者实时处理数据。 

  • 分区键用于在流中按分片分组数据。 

  • Kinesis Data Streams将属于流的数据记录分隔到多个分片中。 

  • 它使用与每个数据记录关联的分区键来确定给定数据记录属于哪个分片。 

  • 消费者从Amazon Kinesis Data Streams获取记录,对其进行处理,并将结果存储在Amazon DynamoDB、Amazon Redshift、Amazon S3等中。

  • 这些消费者也被称为Amazon Kinesis Data Streams应用程序。 

  • 开发能够处理KDS数据流中的数据的自定义消费者应用程序的一种方法是使用Kinesis Client Library(KCL)。

Kinesis消费者应用程序是如何实现水平扩展的呢? 

Kinesis Client Library确保每个分片都有一个记录处理器正在运行,并处理来自该分片的数据。KCL帮助您从Kinesis数据流中消费和处理数据,通过处理与分布式计算和可扩展性相关的许多复杂任务。它连接到数据流,枚举数据流中的分片,并使用租约来协调分片与其消费者应用程序之间的关联。

每个分片都会实例化一个记录处理器来管理。KCL从数据流中拉取数据记录,将记录推送给相应的记录处理器,并检查点处理过的记录。更重要的是,当工作实例数量发生变化或数据流重新分片(分片拆分或合并)时,它会平衡分片-工作器的关联(租约)。这意味着您可以通过添加更多实例来扩展Kinesis Data Streams应用程序,因为KCL会自动在实例之间平衡分片。

但是,当负载增加时,您仍然需要一种方法来扩展应用程序。当然,您可以手动进行操作或构建自定义解决方案来完成此操作。

这就是Kubernetes事件驱动自动缩放(KEDA)的用武之地。KEDA是基于Kubernetes的事件驱动自动缩放组件,它可以监视Kinesis等事件源,并根据需要处理的事件数量来调整底层的部署(和Pod)的规模。

为了观察自动扩展的过程,您将使用一个使用Kinesis Client Library(KCL)2.x从Kinesis数据流中消费数据的Java应用程序。它将部署到Amazon EKS上的Kubernetes集群,并将使用KEDA进行自动缩放。该应用程序包括一个ShardRecordProcessor的实现,该实现处理来自Kinesis流的数据,并将其持久化到DynamoDB表中。我们将使用AWS CLI向Kinesis流中产生数据,并观察应用程序的扩展情况。

在我们深入研究之前,这里是对KEDA的快速概述。


什么是KEDA? 

KEDA是一个构建在原生Kubernetes原语(如Horizontal Pod Autoscaler)之上的开源CNCF项目,可以添加到任何Kubernetes集群中。以下是其关键组件的高级概述(您可以参考KEDA文档进行深入了解):

  • KEDA中的keda-operator-metrics-apiserver组件充当Kubernetes度量服务器,用于公开Horizontal Pod Autoscaler的度量指标。

  • KEDA Scaler与外部系统(如Redis)集成,以获取这些指标(例如列表长度),根据需要处理的事件数量来驱动Kubernetes中任何容器的自动扩展。

  • keda-operator组件的作用是激活和停用Deployment,即将其扩展到零或从零缩减。

您将看到Kinesis Stream KEDA Scaler的实际效果,它会根据AWS Kinesis Stream的分片数量进行自动扩展。

现在让我们继续进行本文的实际部分。


先决条件 

除了一个AWS账户之外,您还需要安装AWS CLI、kubectl、Docker、Java 11和Maven。

设置一个EKS集群,创建一个DynamoDB表和一个Kinesis数据流 

有多种方法可以创建Amazon EKS集群。我喜欢使用eksctl CLI,因为它提供了很多便利。使用eksctl创建EKS集群可以非常简单,就像这样:

eksctl create cluster --name <cluster name> --region <region e.g. us-east-1>

有关详细信息,请参阅Amazon EKS - eksctl文档中的入门指南。

创建一个DynamoDB表来持久化应用程序数据。您可以使用AWS CLI使用以下命令创建表格:

aws dynamodb create-table \    --table-name users \    --attribute-definitions AttributeName=email,AttributeType=S \    --key-schema AttributeName=email,KeyType=HASH \    --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

使用AWS CLI创建一个具有两个分片的Kinesis流,请执行以下命令:

aws kinesis create-stream --stream-name kinesis-keda-demo --shard-count 2

请克隆该GitHub仓库,并切换到正确的目录:

git clone https://github.com/abhirockzz/kinesis-keda-autoscalingcd kinesis-keda-autoscaling

好的,让我们开始吧!


在EKS上设置和配置KEDA 

在本教程中,您将使用YAML文件来部署KEDA。但是您也可以使用Helm charts。

安装KEDA:

# update version 2.8.2 if required

kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.8.2/keda-2.8.2.yaml

验证安装:

# check Custom Resource Definitions
kubectl get crd

# check KEDA Deployments
kubectl get deployment -n keda

# check KEDA operator logs
kubectl logs -f $(kubectl get pod -l=app=keda-operator -o jsonpath='{.items[0].metadata.name}' -n keda) -n keda

配置IAM角色

KEDA操作员和Kinesis消费应用程序需要调用AWS API。由于两者都将作为EKS中的部署运行,我们将使用服务账号的IAM角色(IRSA)来提供必要的权限。

在这种情况下:

  • KEDA操作员需要能够获取Kinesis流的分片数量:它通过使用DescribeStreamSummary API来实现。 

  • 应用程序(具体而言是KCL库)需要与Kinesis和DynamoDB进行交互:它需要一系列的IAM权限来实现这一点。 

配置KEDA操作员的IRSA 

将AWS帐户ID和OIDC身份提供者设置为环境变量:


ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)

#update the cluster name and region as required
export EKS_CLUSTER_NAME=demo-eks-cluster
export AWS_REGION=us-east-1

OIDC_PROVIDER=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")

创建一个包含角色的受信任实体的JSON文件:

read -r -d '' TRUST_RELATIONSHIP <<EOF{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"      },      "Action": "sts:AssumeRoleWithWebIdentity",      "Condition": {        "StringEquals": {          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com",          "${OIDC_PROVIDER}:sub": "system:serviceaccount:keda:keda-operator"        }      }    }  ]}EOFecho "${TRUST_RELATIONSHIP}" > trust_keda.json

现在,创建IAM角色并附加策略(请查看policy_kinesis_keda.json文件以获取详细信息):​​​​​​​

export ROLE_NAME=keda-operator-kinesis-role

aws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://trust_keda.json --description "IRSA for kinesis KEDA scaler on EKS"

aws iam create-policy --policy-name keda-kinesis-policy --policy-document file://policy_kinesis_keda.json
aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn=arn:aws:iam::${ACCOUNT_ID}:policy/keda-kinesis-policy

关联IAM角色和服务账号:


kubectl annotate serviceaccount -n keda keda-operator eks.amazonaws.com/role-arn=arn:aws:iam::${ACCOUNT_ID}:role/${ROLE_NAME}

# verify the annotation 
kubectl describe serviceaccount/keda-operator -n keda

您需要重新启动KEDA操作员部署以使其生效:


kubectl rollout restart deployment.apps/keda-operator -n keda

# to verify, confirm that the KEDA operator has the right environment variables
kubectl describe pod -n keda $(kubectl get po -l=app=keda-operator -n keda --output=jsonpath={.items..metadata.name}) | grep "^\s*AWS_"

# expected output

AWS_STS_REGIONAL_ENDPOINTS:   regional
AWS_DEFAULT_REGION:           us-east-1
AWS_REGION:                   us-east-1
AWS_ROLE_ARN:                 arn:aws:iam::<AWS_ACCOUNT_ID>:role/keda-operator-kinesis-role
AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token

为KCL消费者应用程序配置IRSA

首先创建一个Kubernetes服务帐号:​​​​​​​

kubectl apply -f - <<EOFapiVersion: v1kind: ServiceAccountmetadata:  name: kcl-consumer-app-saEOF

创建一个包含角色的受信实体的JSON文件:​​​​​​​

read -r -d '' TRUST_RELATIONSHIP <<EOF{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"      },      "Action": "sts:AssumeRoleWithWebIdentity",      "Condition": {        "StringEquals": {          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com",          "${OIDC_PROVIDER}:sub": "system:serviceaccount:default:kcl-consumer-app-sa"        }      }    }  ]}EOFecho "${TRUST_RELATIONSHIP}" > trust.json

现在,创建IAM角色并附加策略(请查看policy.json文件以获取详细信息):

export ROLE_NAME=kcl-consumer-app-role

aws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://trust.json --description "IRSA for KCL consumer app on EKS"

aws iam create-policy --policy-name kcl-consumer-app-policy --policy-document file://policy.json

aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn=arn:aws:iam::${ACCOUNT_ID}:policy/kcl-consumer-app-policy

关联IAM角色和服务账号:


kubectl annotate serviceaccount -n default kcl-consumer-app-sa eks.amazonaws.com/role-arn=arn:aws:iam::${ACCOUNT_ID}:role/${ROLE_NAME}

# verify the annotation
kubectl describe serviceaccount/kcl-consumer-app-sa

核心基础架构已准备就绪。让我们准备并部署消费者应用程序。


将KCL消费者应用程序部署到EKS 

首先,您需要构建Docker镜像并将其推送到Amazon Elastic Container Registry(ECR)(请参阅Dockerfile获取详细信息)。

构建并推送Docker镜像到ECR


# create runnable JAR file
mvn clean compile assembly\:single

# build docker image
docker build -t kcl-consumer-app .

AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)

# create a private ECR repo
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com

aws ecr create-repository --repository-name kcl-consumer-app --region us-east-1

# tag and push the image
docker tag kcl-consumer-app:latest $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kcl-consumer-app:latest
docker push $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kcl-consumer-app:latest

部署消费者应用程序

更新consumer.yaml文件,将刚刚推送到ECR的Docker镜像包含在内。其他部分的清单保持不变。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kcl-consumer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kcl-consumer
  template:
    metadata:
      labels:
        app: kcl-consumer
    spec:
      serviceAccountName: kcl-consumer-app-sa
      containers:
        - name: kcl-consumer
          image: AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kcl-consumer-app:latest
          imagePullPolicy: Always
          env:
            - name: STREAM_NAME
              value: kinesis-keda-demo
            - name: TABLE_NAME
              value: users
            - name: APPLICATION_NAME
              value: kinesis-keda-demo
            - name: AWS_REGION
              value: us-east-1
            - name: INSTANCE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name

创建部署(Deployment):


kubectl apply -f consumer.yaml

# verify Pod transition to Running state
kubectl get pods -w

KEDA 中的 KCL 应用自动扩展

现在您已经部署了消费者应用程序,KCL 库应该开始运行了。它首先会在 DynamoDB 中创建一个“控制表”,这个表的名称应与 KCL 应用程序的名称相同(在本例中为 kinesis-keda-demo)。

初始的协调和表的创建可能需要几分钟时间。您可以查看消费者应用程序的日志来跟踪进展。

kubectl logs -f $(kubectl get po -l=app=kcl-consumer --output=jsonpath={.items..metadata.name})

完成租赁分配后,请检查表并注意 leaseOwner 属性:​​​​​​​

aws dynamodb describe-table --table-name kinesis-keda-demoaws dynamodb scan --table-name kinesis-keda-demo

现在,让我们使用 AWS CLI 向 Kinesis 流发送一些数据。​​​​​​​

kubectl apply -f consumer.yaml

# verify Pod transition to Running state
kubectl get pods -w

KCL 应用程序将每条记录持久化到目标 DynamoDB 表中(在本例中为 users)。您可以检查该表以验证记录。

aws dynamodb scan --table-name users

注意 processed_by 属性的值?它与 KCL 消费者 Pod 的名称相同。这将使我们更容易验证端到端的自动扩展过程。

创建 Kinesis 的 KEDA Scaler 

以下是 ScaledObject 的定义。请注意,它针对的是 kcl-consumer Deployment(我们刚刚创建的那个),并且 shardCount 设置为 1:​​​​​​​

apiVersion: keda.sh/v1alpha1kind: ScaledObjectmetadata:  name: aws-kinesis-stream-scaledobjectspec:  scaleTargetRef:    name: kcl-consumer  triggers:    - type: aws-kinesis-stream      metadata:        # Required        streamName: kinesis-keda-demo        # Required        awsRegion: "us-east-1"        shardCount: "1"        identityOwner: "operator"

创建 KEDA Kinesis Scaler:

kubectl apply -f keda-kinesis-scaler.yaml

验证 KCL 应用程序的自动伸缩 

我们从一个 KCL 应用程序的 Pod 开始。但是,多亏了 KEDA,我们现在应该看到第二个 Pod 正在启动。​​​​​​​

kubectl get pods -l=app=kcl-consumer -w

# check logs of the new pod
kubectl logs -f <enter Pod name>

我们的应用程序能够根据 ScaledObject 定义中的 shardCount: "1" 自动扩展到两个 Pod。这意味着 Kinesis 流中的每个 shard 都会有一个 Pod。

在 DynamoDB 中检查 kinesis-keda-demo 控制表:您应该看到 leaseOwner 的更新。

让我们向 Kinesis 流发送更多的数据。

export KINESIS_STREAM=kinesis-keda-demo

aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user5@foo.com --data $(echo -n '{"name":"user5", "city":"new york"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user6@foo.com --data $(echo -n '{"name":"user6", "city":"tel aviv"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user7@foo.com --data $(echo -n '{"name":"user7", "city":"new delhi"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user8@foo.com --data $(echo -n '{"name":"user8", "city":"seattle"}' | base64)

验证 "processed_by" 属性的值。由于我们已经扩展到两个 Pod,每条记录的值应该不同,因为每个 Pod 将处理 Kinesis 流的一部分记录。

增加 Kinesis 流容量 

让我们将 shard 的数量从两个扩展到三个,并继续监视 KCL 应用程序的自动缩放。

aws kinesis update-shard-count --stream-name kinesis-keda-demo --target-shard-count 3 --scaling-type UNIFORM_SCALING

一旦 Kinesis 重新划分完成,KEDA 扩展器将开始工作,将 KCL 应用程序扩展到三个 Pod。

kubectl get pods -l=app=kcl-consumer -w

就像之前一样,确认在 DynamoDB 的 kinesis-keda-demo 控制表中,Kinesis shard 的租约已更新。检查 leaseOwner 属性。

继续向 Kinesis 流发送更多数据。正如预期的那样,Pod 将共享记录处理,并且在 users 表中的 processed_by 属性中会反映出来。

export KINESIS_STREAM=kinesis-keda-demo

aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user9@foo.com --data $(echo -n '{"name":"user9", "city":"new york"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user10@foo.com --data $(echo -n '{"name":"user10", "city":"tel aviv"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user11@foo.com --data $(echo -n '{"name":"user11", "city":"new delhi"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user12@foo.com --data $(echo -n '{"name":"user12", "city":"seattle"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user14@foo.com --data $(echo -n '{"name":"user14", "city":"tel aviv"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user15@foo.com --data $(echo -n '{"name":"user15", "city":"new delhi"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user16@foo.com --data $(echo -n '{"name":"user16", "city":"seattle"}' | base64)

缩小规模 

到目前为止,我们只进行了单向的扩展。当我们减少 Kinesis 流的分片容量时会发生什么?自己尝试一下:将分片数量从三个减少到两个,观察 KCL 应用的情况。

一旦您验证了端到端的解决方案,应清理资源,以避免产生额外的费用。


删除资源 

删除 EKS 集群、Kinesis 流和 DynamoDB 表。​​​​​​​

eksctl delete cluster --name keda-kinesis-demoaws kinesis delete-stream --stream-name kinesis-keda-demoaws dynamodb delete-table --table-name users

结论

在本文中,您学习了如何使用 KEDA 自动扩展从 Kinesis 流中消费数据的 KCL 应用程序。

您可以根据应用程序的要求配置 KEDA 扩展器。例如,您可以将 shardCount 设置为 3,并为 Kinesis 流中的每三个分片设置一个 Pod。但是,如果您希望保持一对一的映射关系,可以将 shardCount 设置为 1,KCL 将负责分布式协调和租约分配,确保每个 Pod 具有一个记录处理器的实例。这是一种有效的方法,可以根据应用程序的需求扩展 Kinesis 流处理管道,以满足需求。

作者:Abhishek Gupta

更多技术干货请关注公号“云原生数据库

squids.cn,基于公有云基础资源,提供云上 RDS,云备份,云迁移,SQL 窗口门户企业功能,

帮助企业快速构建云上数据库融合生态。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年陕西彬州第八届半程马拉松赛153pb完赛

1、赛事背景 2023年6月3日&#xff0c;我参加了2023陕西彬州第八届半程马拉松赛&#xff0c;最终153完赛&#xff0c;PB了5分钟。起跑时间早上7点30分&#xff0c;毕竟6月天气也开始热了。天气预报显示当天还是小到中雨&#xff0c;上次铜川宜君半马也是雨天跑的&#xff0c;阴…

lecory 波形二进制文件头(.trc)定义

1.文件头&#xff0c;从0字节开始 byte[] lecroy_trc_header new byte[]{0x23,0x39,0x30,0x30,0x32,0x30,0x30,0x30,0x31,0x34,0x34,0x57,0x41,0x56,0x45,0x44,0x45,0x53,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4C,0x45,0x43,0x52,0x4F,0x59,0x5F,0x32,0x5F,0x33,0x…

研发工程师玩转Kubernetes——使用Ingress进行路由

依据微服务理念&#xff0c;我们希望每个独立的功能由一个服务支持。比如有两个接口&#xff1a;http://www.xxx.com/plus和http://www.xxx.com/minus&#xff0c;前者由一个叫plus-service的服务支持&#xff0c;后者由一个叫minus-service的服务支持。这样就需要一个路由层&a…

Revit问题:创建牛腿柱和快速生成圈梁

一、Revit中如何用体量创建牛腿柱 牛腿&#xff1a;悬臂体系的挂梁与悬臂间必然出现搁置构造&#xff0c;通常就将悬臂端和挂梁端的局部构造&#xff0c;又称梁托。牛腿的作用是衔接悬臂梁与挂梁&#xff0c; 并传递来自挂梁的荷载。牛腿柱可以用于桥梁、厂房的搭建&#xff0c…

西南财经大学李玉周:数智化技术广泛使用推动管理会计加快落地

近日&#xff0c;由用友主办的「智能会计 价值财务」2023企业数智化财务创新峰会收官站圆满举办。来自知名院校的专家学者、央国企等大型企业财务领路人相约成都&#xff0c;一同见证“智能会计”新时代的到来&#xff0c;并肩探讨“价值财务”新主张。 为更好传递智能会计对企…

【接口测试】JMeter接口关联测试

‍‍1 前言 我们来学习接口管理测试&#xff0c;这就要使用到JMeter提供的JSON提取器和正则表达式提取器了&#xff0c;下面我们来看看是如何使用的吧。 2 JSON提取器 1、添加JSON提取器 在线程组右键 > 添加 > 后置处理器 > JSON提取器 2、JSON提取器参数说明 N…

chatgpt赋能python:Python如何删除行:从入门到精通

Python如何删除行&#xff1a;从入门到精通 在Python编程中&#xff0c;删除行是必不可少的操作之一。无论是清除不必要的数据&#xff0c;还是在数据集中删除重复行&#xff0c;或者在文本文件中删除某些行&#xff0c;删除行都是一项极其重要的任务。 什么是Python语言&…

Shell脚本攻略:文本三剑客之sed

目录 一、理论 1.sed 二、实验 1.sed命令的寻址打印 2.显示奇偶 3.查找替换 4.后向引用 一、理论 1.sed (1) 概念 sed 英文全称为stream editor流式编辑器&#xff0c;sed 对输入流&#xff08;文件或来自管道的输入&#xff09;执行基本文本转换单通过流&#xff0c;…

Matlab进阶绘图第22期—不等宽柱状图

不等宽柱状图是一种特殊的柱状图。 与常规柱状图相比&#xff0c;不等宽柱状图可以通过柱高与柱宽分别表达两个维度的数据&#xff0c;因此在多个领域得到应用。 在《Matlab论文插图绘制模板第91期》中&#xff0c;虽有介绍过利用Matlab自带bar函数绘制不等宽柱状图的方法&am…

高完整性系统(7)Formal Verification and Validation

文章目录 Specification Process 规格化过程State Invariants案例check ... expect Alloy是一种用于构建和检查抽象模型的语言和工具。当Alloy说所有断言都成立时&#xff0c;这意味着你的模型或规格在给定范围内已成功通过了所有的断言检查。换句话说&#xff0c;对于你所定义…

C#实例:多功能Windows窗体应用程序Helloworld_WinForm

有了创建一个Windows窗体应用程序的经验&#xff0c;就可以开始尝试运用更多的控件实现更多丰富的功能界面。以下分享我基于项目Helloworld_WinForm使用常用C#Windows窗体控件实现一些小功能。 每一节标题为所用到的控件&#xff0c;全文以实际制作过程为序编制。 目录 WinFor…

来了解一下白盒测试,黑盒测试,灰盒测试吧(超详解~)

根据被测对象的不同&#xff0c;软件测试可以分为白盒测试、黑盒测试、灰盒测试三种方式。那么&#xff0c;这三种测试方式具体是如何运行的&#xff1f;各有什么特点&#xff1f;下面&#xff0c;跟着静姐一起了解一下吧&#xff01; 01、白盒测试 WHITE BOX ●概念&#x…

PACS影像解决方案

现代医学影像技术的迅猛发展&#xff0c;使得PACS系统已逐渐成为各级医院实现信息化建设的重要组成部分。医学影像技术的进步也提升了医学影像的清晰度&#xff0c;推动二维PACS向三维升级转变。这一切都使得医学影像数据量激增&#xff0c;加之医疗行业法规的数据保存要求&…

Android平台OpenCV入门

一、导入OpenCV 别忘记把libopencv_java3.so添加进来。 二、初始化 OpenCVLoader.initDebug();三、常用方法 1. CvType 数据类型 以CV_64FC2为例&#xff0c;64指64位&#xff0c;F指浮点数&#xff0c;C指通道&#xff0c;2为2通道。 数值具体类型取值范围CV_8U8 位无符…

软件工程导论(四)软件编码测试与维护

一、软件编程 1.1良好的编程习惯 变量命名有意义并且使用统一的命名规则 编写自文档代码&#xff08;序言性注释 or 行内注释&#xff09; 提前进行可维护性考量&#xff08;可以用常量的方式存在的数值最好以变量的方式存在&#xff09; 良好的视觉安排可以提高代码的可读性(…

SOLIDWORKS技巧培训-绘制零件滚花的两种方法

最近常有朋友咨询SolidWorks零件如何做滚花的效果&#xff0c;下面给大家整理了绘制零件滚花的一个培训教程&#xff1a; 作为机械设计师&#xff0c;滚花应该都不陌生&#xff0c;真要说起来&#xff0c;滚花绘制其实也不算难&#xff0c;跟着我们一步一步来&#xff0c;应该…

ThreeJS 炫酷特效旋转多面体Web页 Demo 01《ThreeJS 炫酷特效制作》

本案例为一个 threejs 的特效网页&#xff0c;大小球体进行包裹&#xff0c;外球体为透明材质&#xff0c;但是进行了线框渲染&#xff0c;使其能够通过外球踢查看其内球体。 注&#xff1a;案例参考源于互联网&#xff0c;在此做代码解释&#xff0c;侵删 本案例除 ThreeJS 外…

chatgpt赋能python:Python如何分割列表

Python如何分割列表 介绍 在Python编程中&#xff0c;列表是一种非常常见的数据类型。有时候我们需要将一个大的列表分割成几个小的列表&#xff0c;以便更好地处理数据。Python提供了多种方法来实现这个目的。在本文中&#xff0c;我们将介绍Python中如何分割列表的几种方法…

活动预告 | 中国数据库联盟(ACDU)中国行定档深圳,一起揭秘数据库前沿技术

在当今数字化时代&#xff0c;数据库是各行各业中最核心的信息管理系统之一。随着技术的飞速发展&#xff0c;数据库领域也不断涌现出新的前沿技术和创新应用。数据库运维和开发人员需要紧跟前沿技术&#xff0c;才能保持竞争力&#xff0c;并实现更高效、更智能、更人性化的应…

pytorch实战 -- 神经网络

softmax的基本概念 交叉熵损失函数 模型训练和预测 在训练好softmax回归模型后&#xff0c;给定任一样本特征&#xff0c;就可以预测每个输出类别的概率。通常&#xff0c;我们把预测概率最大的类别作为输出类别。如果它与真实类别&#xff08;标签&#xff09;一致&#xff0…