当前位置: 首页 > news >正文

aws(学习笔记第十五课) 如何从灾难中恢复(recover)

aws(学习笔记第十五课)

  • 如何从灾难中恢复

学习内容:

  • 使用CloudWatch对服务器进行监视与恢复
  • 区域(region),可用区(available zone)和子网(subnet)
  • 使用自动扩展(AutoScalingGroup)

1. 使用CloudWatch对服务器进行监视与恢复

  1. 整体架构
    这里模拟Jenkins Server在灾难时候,可以由AWS Cloudwatch Alarm监视到,之后将其recover
    在这里,elastic ip定义了,并且将其指向了Jenkins Server。为什么平时没有使用elastic ip,这里特意使用它呢。
    因为默认如果让AWS自动配置给ec2internet ip,都是临时的ip,每次ec2实例重启了之后,都会重新分配ip。但是作为Jenkins Server来使用,并且一旦从灾难中recover之后,ip address变化的话,运用起来将会特别不方便。

在这里插入图片描述
2. 代码解析

  • 代码
    {"AWSTemplateFormatVersion": "2010-09-09","Description": " (Jenkins (CI server) running on EC2 with AWS CloudWatch recovery)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"}},"Mappings": {"EC2RegionMap": {"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"Subnet": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet"			},"RouteTableAssociation": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "Subnet"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociation": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "Subnet"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroup": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"ElasticIP": {"Type": "AWS::EC2::EIP","Properties": {"InstanceId": {"Ref": "Server"},"Domain": "vpc"},"DependsOn": "GatewayToInternet"},"Server": {"Type": "AWS::EC2::Instance","Properties": {"ImageId": {"Fn::FindInMap": ["EC2RegionMap", {"Ref": "AWS::Region"}, "AmazonLinuxAMIHVMEBSBacked64bit"]},"InstanceType": "t2.micro","KeyName": {"Ref": "KeyName"},"SecurityGroupIds": [{"Ref": "SecurityGroup"}],"SubnetId": {"Ref": "Subnet"},"UserData": {"Fn::Base64": {"Fn::Join": ["", ["#!/bin/bash -ex\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]},"DependsOn": "GatewayToInternet"},"RecoveryAlarm": {"Type": "AWS::CloudWatch::Alarm","Properties": {"AlarmDescription": "Recover server when underlying hardware fails.","Namespace": "AWS/EC2" ,"MetricName": "StatusCheckFailed_System","Statistic": "Minimum","Period": "60","EvaluationPeriods": "5","ComparisonOperator": "GreaterThanThreshold","Threshold": "0","AlarmActions": [{"Fn::Join": ["", ["arn:aws:automate:", { "Ref": "AWS::Region"}, ":ec2:recover"]]}],"Dimensions": [{"Name": "InstanceId", "Value": {"Ref": "Server"}}]}}},"Outputs": {"JenkinsURL": {"Description": "URL to access web interface of Jenkins server.","Value": {"Fn::Join": ["", ["http://", {"Ref": "ElasticIP"}, ":8080"]]}},"User": {"Description": "Administrator user for Jenkins.","Value": "admin"},"Password": {"Description": "Password for Jenkins administrator user.","Value": {"Ref": "JenkinsAdminPassword"}}}
    }
    
  • 分析
    • 这里使用了AWS:CloudWatch:Alarm,如下所示。
      "RecoveryAlarm": {"Type": "AWS::CloudWatch::Alarm","Properties": {"AlarmDescription": "Recover server when underlying hardware fails.","Namespace": "AWS/EC2" ,"MetricName": "StatusCheckFailed_System","Statistic": "Minimum","Period": "60","EvaluationPeriods": "5","ComparisonOperator": "GreaterThanThreshold","Threshold": "0","AlarmActions": [{"Fn::Join": ["", ["arn:aws:automate:", { "Ref": "AWS::Region"}, ":ec2:recover"]]}],"Dimensions": [{"Name": "InstanceId", "Value": {"Ref": "Server"}}]}}
      
      这里,设置了AWS::CloudWatch::Alarm,每隔60秒检查下ec2的状态,如有ec2有问题,那么使用arn:aws:automate:进行在其他的Available Zone恢复,但是这里无法让ec2 server模拟出问题的场合,所以这里不能实际上让arn:aws:automate:ec2:recover发生。

2. 区域(region),可用区(available zone)和子网(subnet)

  1. 区域(region),可用区(available zone)
    • 一个区域(region)里面,包含多个可用区(available zone),每个可用区(available zone)有多个数据中心(DataCenter)。
    • 不同区域(region)的之间通过低延时的链路链接。可以想象,在同一个region的服务之前的网络延时会非常小。
      在这里插入图片描述
  2. 全球性的服务跨多个区域
    • 各种服务的不同区域
      在这里插入图片描述
  3. VPC,区域(region)以及子网(subnet
    • VPC一定会属于一个区域(region
    • 子网(subnet)一定属于一个可用区(Availibility Zone
      在这里插入图片描述

3. 使用自动扩展(AutoScalingGroup)

  1. 使用自动扩展(AutoScalingGroup),可以保证执行数量的虚拟服务器一直运行。

    • 代码
      {"AWSTemplateFormatVersion": "2010-09-09","Description": "(Jenkins (CI server) running with Auto Scaling Group over multiple AZs)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"}},"Mappings": {"EC2RegionMap": {"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetA": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetB": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["1", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.1.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet"},"RouteTableAssociationA": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"RouteTableId": {"Ref": "RouteTable"}}},"RouteTableAssociationB": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociationA": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"NetworkAclAssociationB": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroupJenkins": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"LaunchTemplate": {"Type": "AWS::EC2::LaunchTemplate","Properties": {"LaunchTemplateName": "LaunchTemplate","LaunchTemplateData":{"ImageId": {"Fn::FindInMap": ["EC2RegionMap", {"Ref": "AWS::Region"}, "AmazonLinuxAMIHVMEBSBacked64bit"]},"KeyName": {"Ref": "KeyName"},"NetworkInterfaces":[{"DeviceIndex":0,"AssociatePublicIpAddress":true,"Groups":[{"Ref": "SecurityGroupJenkins"}],"DeleteOnTermination":true}],"InstanceType": "t2.micro","UserData": {"Fn::Base64": {"Fn::Join": ["",["#!/bin/bash -ex\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}}}}},"AutoScalingGroup": {"Type": "AWS::AutoScaling::AutoScalingGroup","Properties": {"LaunchTemplate" : {"LaunchTemplateId" : {"Ref" : "LaunchTemplate"},"Version" : {"Fn::GetAtt" : ["LaunchTemplate","LatestVersionNumber"]}},"Tags": [{"Key": "Name","Value": "jenkins-multiaz","PropagateAtLaunch": true}],"DesiredCapacity": 1,"MinSize": 1,"MaxSize": 1,"VPCZoneIdentifier": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}],"HealthCheckGracePeriod": 600,"HealthCheckType": "EC2"},"DependsOn": "GatewayToInternet"}}
      }
      
    • 代码解析
      • AutoScalingGroup设定了两个subnet,可以在一个subnetEC2 server出现问题的时候,在另一个subnet启动另一个EC2 server
        在这里插入图片描述
      • subnet Asubnet B
        每个subnet都在不同的Availability Zone
        在这里插入图片描述
    • 创建一个jenkins task
      在这里插入图片描述
    • 删除jenkins实例
      在这里插入图片描述
    • 检测Auto Scaling Group的动作
      可以看到Auto Scaling Group会马上启动另一个EC2 server来支持jenkins服务。

    在这里插入图片描述
    注意,这里,IP地址和建立的jenkins task都已经没有了,接下来解决两个问题。

  2. 使用AMI进行恢复。

    • 在现在的jenkins server上建立task
      在这里插入图片描述
    • 对当前的jenkins server保存镜像
      Dell@DESKTOP-DHMQMJG MINGW64 ~/.ssh
      $ aws ec2 create-image --instance-id i-05593a7ba7b94e566 --name jenkins-multiaz
      {"ImageId": "ami-01ed9b718c5a467c4"
      }
      
    • cloudformation进行更新
      *在参数中增加AMISnapshot,稍后更新CloudFormation的时候会选择上面建立的AMI
      在这里插入图片描述
      • cloudformation进行更新,LaunchTemplate里面设定AMI参数

        • 在参数中增加AMISnapshot,稍后更新CloudFormation的时候会选择上面建立的AMI

        在这里插入图片描述

        • cloudformation进行更新
          在这里插入图片描述
      • Cloudformation更新成功
        在这里插入图片描述

      • 删除当前的Jenkins server
        在这里插入图片描述

      • 重启之后的jenkins server确认
        可以看到上面建立的jenkins task已经保留过来了,原因是使用了AMI,对当前的EBS进行了保存。
        在这里插入图片描述

    • cloudformation代码
      {"AWSTemplateFormatVersion": "2010-09-09","Description": "AWS in Action: chapter 11 (Jenkins (CI server) running with Auto Scaling Group over multiple AZs)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"},"AMISnapshot": {"Description": "AMI ID to start virtual server from.","Type": "String","AllowedPattern" : "[\u0020-\uD7FF\uE000-\uFFFD\uD800\uDC00-\uDBFF\uDFFF\r\n\t]*","MinLength" : "1","MaxLength" : "255"}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetA": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetB": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["1", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.1.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet"},"RouteTableAssociationA": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"RouteTableId": {"Ref": "RouteTable"}}},"RouteTableAssociationB": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociationA": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"NetworkAclAssociationB": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroupJenkins": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"LaunchTemplate": {"Type": "AWS::EC2::LaunchTemplate","Properties": {"LaunchTemplateName": "LaunchTemplate","LaunchTemplateData":{"ImageId": {"Ref": "AMISnapshot"},"KeyName": {"Ref": "KeyName"},"NetworkInterfaces":[{"DeviceIndex":0,"AssociatePublicIpAddress":true,"Groups":[{"Ref": "SecurityGroupJenkins"}],"DeleteOnTermination":true}],"InstanceType": "t2.micro","UserData": {"Fn::Base64": {"Fn::Join": ["",["#!/bin/bash -ex\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}}}}},"AutoScalingGroup": {"Type": "AWS::AutoScaling::AutoScalingGroup","Properties": {"LaunchTemplate" : {"LaunchTemplateId" : {"Ref" : "LaunchTemplate"},"Version" : {"Fn::GetAtt" : ["LaunchTemplate","LatestVersionNumber"]}},"Tags": [{"Key": "Name","Value": "jenkins-multiaz","PropagateAtLaunch": true}],"DesiredCapacity": 1,"MinSize": 1,"MaxSize": 1,"VPCZoneIdentifier": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}],"HealthCheckGracePeriod": 600,"HealthCheckType": "EC2"},"DependsOn": "GatewayToInternet"}}
      }
      
  3. 使用elastic IP进行对网络接口进行固定。

    • IP地址每次都要发生变化,还是不理想。
    • 利用elastic IP进行网络接口的固定
    • 修改的代码
      • 设定IamRole

        "IamRole": {"Type": "AWS::IAM::Role","Properties": {"AssumeRolePolicyDocument": {"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": ["ec2.amazonaws.com"]},"Action": ["sts:AssumeRole"]}]},"Path": "/","Policies": [{"PolicyName": "root","PolicyDocument": {"Version": "2012-10-17","Statement": [{"Action": ["ec2:AssociateAddress"],"Resource": ["*"],"Effect": "Allow"}]}}]}},"IamInstanceProfile": {"Type": "AWS::IAM::InstanceProfile","Properties": {"Path": "/","Roles": [{"Ref": "IamRole"}]}},
        

        在这里插入图片描述

        • LaunchTemplate设定IamRole参数
          这里主要是为了给EC2 server实例设定IamRole,以便EC2 server能够执行aws ec2 associate-address命令,在灾难恢复的时候设定固定的Elastic IP
          在这里插入图片描述
        • 更新cloudformation堆栈
          在这里插入图片描述
        • Elastic IP整体代码
          {"AWSTemplateFormatVersion": "2010-09-09","Description": "AWS in Action: chapter 11 (Jenkins (CI server) running with Auto Scaling Group over multiple AZs)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"},"AMISnapshot": {"Description": "AMI ID to start virtual server from.","Type": "String","AllowedPattern" : "[\u0020-\uD7FF\uE000-\uFFFD\uD800\uDC00-\uDBFF\uDFFF\r\n\t]*","MinLength" : "1","MaxLength" : "255"}},"Mappings": {"EC2RegionMap": {"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetA": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetB": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["1", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.1.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet"},"RouteTableAssociationA": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"RouteTableId": {"Ref": "RouteTable"}}},"RouteTableAssociationB": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociationA": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"NetworkAclAssociationB": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroupJenkins": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"IamRole": {"Type": "AWS::IAM::Role","Properties": {"AssumeRolePolicyDocument": {"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": ["ec2.amazonaws.com"]},"Action": ["sts:AssumeRole"]}]},"Path": "/","Policies": [{"PolicyName": "AttachIP","PolicyDocument": {"Version": "2012-10-17","Statement": [{"Action": ["ec2:AssociateAddress"],"Resource": ["*"],"Effect": "Allow"}]}}]}},"IamInstanceProfile": {"Type": "AWS::IAM::InstanceProfile","Properties": {"Path": "/","Roles": [{"Ref": "IamRole"}]}},"ElasticIP": {"Type": "AWS::EC2::EIP","Properties": {"Domain": "vpc"},"DependsOn": "GatewayToInternet"},"LaunchTemplate": {"Type": "AWS::EC2::LaunchTemplate","Properties": {"LaunchTemplateName": "LaunchTemplate","LaunchTemplateData":{"ImageId": {"Ref": "AMISnapshot"},"KeyName": {"Ref": "KeyName"},"IamInstanceProfile": { "Arn": {"Fn::GetAtt": ["IamInstanceProfile","Arn"]}},"NetworkInterfaces":[{"DeviceIndex":0,"AssociatePublicIpAddress":true,"Groups":[{"Ref": "SecurityGroupJenkins"}],"DeleteOnTermination":true}],"InstanceType": "t2.micro","UserData": {"Fn::Base64": {"Fn::Join": ["",["#!/bin/bash -ex\n","aws configure set default.region ", {"Ref": "AWS::Region"},"\n","INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`\n","aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id ", {"Fn::GetAtt": ["ElasticIP", "AllocationId"]}, "\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}}}}},"AutoScalingGroup": {"Type": "AWS::AutoScaling::AutoScalingGroup","Properties": {"LaunchTemplate" : {"LaunchTemplateId" : {"Ref" : "LaunchTemplate"},"Version" : {"Fn::GetAtt" : ["LaunchTemplate","LatestVersionNumber"]}},"Tags": [{"Key": "Name","Value": "jenkins-elasticip","PropagateAtLaunch": true}],"DesiredCapacity": 1,"MinSize": 1,"MaxSize": 1,"VPCZoneIdentifier": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}],"HealthCheckGracePeriod": 600,"HealthCheckType": "EC2"},"DependsOn": "GatewayToInternet"}},"Outputs": {"JenkinsURL": {"Description": "URL to access web interface of Jenkins server.","Value": {"Fn::Join": ["", ["http://", {"Ref": "ElasticIP"}, ":8080"]]}},"User": {"Description": "Administrator user for Jenkins.","Value": "admin"},"Password": {"Description": "Password for Jenkins administrator user.","Value": {"Ref": "JenkinsAdminPassword"}}}
          }
          
        • Jenkins ServerIP地址是Elastic IP
          可以看到IP地址是54.92.85.184,和Elastic IP相同的。

        在这里插入图片描述

        • 删除了Jenkins Server之后,重新启动的的IP地址还是Elastic IP
          在这里插入图片描述

相关文章:

aws(学习笔记第十五课) 如何从灾难中恢复(recover)

aws(学习笔记第十五课) 如何从灾难中恢复 学习内容&#xff1a; 使用CloudWatch对服务器进行监视与恢复区域(region)&#xff0c;可用区(available zone)和子网(subnet)使用自动扩展(AutoScalingGroup) 1. 使用CloudWatch对服务器进行监视与恢复 整体架构 这里模拟Jenkins Se…...

nginx4层限速

Nginx的功能概述 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;也可以作为邮件代理服务器等。它主要工作在7层&#xff08;应用层&#xff09;&#xff0c;但在某些场景下也可以实现部分4层&#xff08;传输层&#xff09;的功能。 关于4层限速 Nginx自身的限制&#x…...

Spring Cloud Alibaba 之 “Feign多参数构造”

在上一篇文章整合好了Feign&#xff0c;现在来总结以下Feign调用多参数方法的使用。 GET方式&#xff1a; Spring Cloud为Feign支持了Spring Mvc注解的。如果请求的是localhost:8083/test?id1&namecoco,那么如果我们这样写&#xff08;User实体类有这二个属性&#xff09…...

C#高级教程

目录 C# 特性&#xff08;Attribute&#xff09;C# 反射&#xff08;Reflection&#xff09;C# 属性&#xff08;Property&#xff09;C# 索引器&#xff08;Indexer&#xff09;C# 委托&#xff08;Delegate&#xff09;C# 事件&#xff08;Event&#xff09;C# 集合&#xf…...

c++ 位图和布隆过滤器

位图&#xff08;bitmap&#xff09; 定义 位图是一种使用位数组存储数据的结构。每一位表示一个状态&#xff0c;通常用于快速判断某个值是否存在&#xff0c;或者用来表示布尔类型的集合。 特点 节省空间&#xff1a;一个字节可以表示8个状态。高效操作&#xff1a;位操作…...

基于Springboot开发的云野旅游平台

一、功能介绍 云野旅游平台包含管理员、用户两个角色以及前后台系统。 前台系统功能 用户登录成功后&#xff0c;可以进行查看旅游路线、最新线路、旅游资讯、个人中心、后台管理、购物车、客服等功能模块。进行相对应操作。 后台系统功能 管理员或用户登录成功后&#xf…...

微服务即时通讯系统(5)用户管理子服务,网关子服务

用户管理子服务&#xff08;user文件&#xff09; 用户管理子服务也是这个项目中的一个业务最多的子服务&#xff0c;接口多&#xff0c;但是主要涉及的数据表只有user表&#xff0c;Redis的键值对和ES的一个搜索引擎&#xff0c;主要功能是对用户的个人信息进行修改管理&#…...

docker.io连接超时的处理,用代理网站

docker pull的时候会超时&#xff1a; Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 这时可以找一些代理网站&#xff0c;比如…...

【测试工具JMeter篇】JMeter性能测试入门级教程(四):JMeter中BeanShell内置方法使用

一、什么是BeanShell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似);BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简…...

JavaScript 键盘控制移动

如果你想通过 JavaScript 实现键盘控制对象&#xff08;比如一个方块&#xff09;的移动&#xff0c;下面是一个简单的示例&#xff0c;展示如何监听键盘事件并根据按下的键来移动一个元素。 HTML 和 CSS&#xff1a; <!DOCTYPE html> <html lang"en">…...

如何预防服务器后台爆破攻击

服务器后台爆破&#xff08;Brute Force Attack&#xff09;是一种通过反复尝试用户名和密码组合&#xff0c;以非法获取系统访问权限的攻击方式。这种攻击不仅会消耗服务器资源&#xff0c;还可能导致合法用户被锁定或敏感数据泄露。为了有效预防服务器后台爆破攻击&#xff0…...

AI 写作(一):开启创作新纪元(1/10)

一、AI 写作&#xff1a;重塑创作格局 在当今数字化高速发展的时代&#xff0c;AI 写作正以惊人的速度重塑着创作格局。AI 写作在现代社会中占据着举足轻重的地位&#xff0c;发挥着不可替代的作用。 随着信息的爆炸式增长&#xff0c;人们对于内容的需求日益旺盛。AI 写作能够…...

【HarmonyOS】鸿蒙应用使用lottie动画

【HarmonyOS】鸿蒙应用使用lottie动画 一、lottie动画是什么&#xff1f; https://airbnb.design/lottie Lottie是由Airbnb团队开发的一个适用于iOS、Android、React Native、Web和Windows的开源动画库&#xff0c;用于解析使用Bodymovin导出为JSON的Adobe After Effects动…...

SQL面试题——腾讯SQL面试题 合并连续支付订单

合并连续支付订单 现有一张用户支付表:user_pay包含字段订单ID,用户ID,商户ID,支付时间,支付金额。如果同一用户在同一商户存在多笔订单,且中间该用户没有其他商户的支付记录,则认为是连续订单,请把连续订单进行合并,时间取最早支付时间,金额求和。 +----------+------…...

【docker】10. 容器操作案例

容器操作案例 容器基本操作 • 通过 nginx 镜像文件创建容器 • 容器的列举(包含正在运行的容器) # 发现此时 e7c33d9f5c61 这个容器运行的状态为 Up,即运行状态 rootLAPTOP-H2EI4I6A:~# docker container ls CONTAINER ID IMAGE COMMAND CREATED …...

postman测试

当然&#xff0c;以下是针对你提供的API层和Service层代码中涉及到的各个接口&#xff0c;如何使用 Postman 进行详细测试的指南。这个指南将帮助你理解如何配置 Postman 来测试这些接口&#xff0c;包括请求的构造、认证的处理、以及如何解读响应。 目录 准备工作接口测试指…...

【攻防实验】溯源与取证分析实验

溯源与取证分析实验 溯源取证分析作为网络攻防过程中重要环节&#xff0c;准确找到攻击者的入侵线索(尤其是攻击突破口、攻击IP地址、域名、工具等信息)&#xff0c;对于企业或者团队安全运营团队来说都是必备技能。常规攻击取证过程中往往会结合流量、Web访问日志、终端系统或…...

【测试工具JMeter篇】JMeter性能测试入门级教程(七):JMeter断言

一、前言 在 JMeter 中&#xff0c;断言元件&#xff08;Assertion&#xff09;用于验证测试结果是否符合预期。断言元件可以检查服务器的响应数据&#xff0c;以确保它们符合期望的模式或值&#xff0c;从而验证性能测试脚本的正确性。断言元件通常在每个请求的响应中添加&am…...

Linux 常用命令

目录 一、ls 指令 二、pwd命令 三、cd 指令 1、cd 目录名 2、cd .. 返回上级目录 3、cd ~ 进入用户家目 4、cd - 返回最近访问目录 5、cd相对路径&&cd绝对路径 四、touch指令 五、mkdir指令 1、mkdir 目录名 创建一个目录 2、mkdir -p 递归创建多…...

汽车IVI中控OS Linux driver开发实操(二十八):回声消除echo cancellation和噪声消除Noise reduction

概述: 在当今高度互联的世界中,清晰的实时通信比以往任何时候都更重要。在远程团队会议期间,没有什么能像回声一样打断对话。当说话者听到他们的声音回响时,可能会分散注意力,甚至无法理解对话。即使是很小的回声也会产生很大的影响,仅仅25毫秒的振幅就足以造成声音干扰…...

003-SpringBoot整合Pagehelper

SpringBoot整合Pagehelper 一、引入依赖二、配置 application.yml三、配置 MybatisPlusConfig四、Controller五、ServiceImpl 一、引入依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</ar…...

零基础学安全--shell练习

目录 用shell写一个计算器 测试​ 一些小问题 n阶乘数 测试 拓展 写⼀个Shell脚本去筛选出eth0⽹卡的ipv4地址&#xff0c;并赋值⼀个变量输出 测试 无限重启 用shell写一个计算器 read -p "请输入数字a: " number1 read -p "请输入操作符&#xf…...

【专题】计算机网络之运输层(传输层)

1. 运输层协议概述 1.1 进程之间的通信 (1) 运输层的作用 运输层提供进程间的逻辑通信。 运输层的屏蔽作用&#xff1a; 运输层向高层用户屏蔽了下面网络核心的细节&#xff08;如网络拓扑、所采用的路由选择协议等&#xff09;&#xff0c;使应用进程看见的就是好像在两个运…...

【leetcode100】旋转图像

1、题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],…...

软件工程——期末复习(1)

名词解释&#xff1a; 名词解释--人月 答案&#xff1a;人月是软件开发工作量的单位&#xff0c;1人月表示1个程序员1个月的工作时间所开发的代码量。 请解释软件缺陷、错误和失败&#xff0c;并简单举例说明。 答案&#xff1a;缺陷&#xff08;defect&#xff09;指系统代…...

HTML5系列(3)--多媒体标签详解

前端技术探索系列&#xff1a;HTML5 多媒体标签详解 &#x1f3a5; 开篇寄语 &#x1f44b; 前端开发者们&#xff0c; 在前三篇文章中&#xff0c;我们探讨了 HTML5 的语义化和表单特性。今天&#xff0c;让我们深入了解 HTML5 的多媒体能力&#xff0c;看看如何构建强大的…...

Spring Boot 3.4.0 发布:功能概览与示例

Spring Boot 3.4.0 带来了许多增强功能&#xff0c;使现代应用开发更加高效、便捷和强大。以下是最新功能的完整概述&#xff0c;以及一些帮助您快速入门的代码示例。 1. 应用程序版本管理 Spring Boot 引入了 spring.application.version 属性&#xff0c;方便开发者设置和访…...

【Vue3】【Naive UI】<n-upload>标签

【Vue3】【Naive UI】标签 基本设置 【VUE3】【Naive UI】&#xff1c;NCard&#xff1e; 标签 【VUE3】【Naive UI】&#xff1c;n-button&#xff1e; 标签 【VUE3】【Naive UI】&#xff1c;a&#xff1e; 标签 【VUE3】【Naive UI】&#xff1c;NDropdown&#xff1e; 标签…...

7.代理模式(Proxy Pattern)

古朗月行 代理模式JDK动态代理代码示例原码分析 cglib动态代理代码示例源码分析 JDK cglib动态代理对比ClassLoader类的生命周期&#xff1a; 参考资料 唐 李白 小时不识月&#xff0c;呼作白玉盘。 又疑瑶台镜&#xff0c;飞在青云端。 仙人垂两足&#xff0c;桂树何团团。…...

【效果】回到顶部功能实现

实现效果&#xff1a; 相关代码&#xff1a; <template><div class"cats" :style"{ top: catsTop }" ref"cats" click"catTop"></div> </template> 样式&#xff1a; /* 回到顶部 - 小猫咪 */ .cats {posi…...

项目搭建+修改

一 : 在列表成功回调函数,追加数据中,添加修改的按钮 for (let x of res) {//追加数据$("#table").append(<tr><td><input type"checkbox" class"ck" value"\${x.uid}"></td><td>\${x.uid}</td>…...

GD库如何根据颜色生成纯色背景图

GD库是一个用于图像处理的PHP扩展模块&#xff0c;它提供了一系列函数来创建、编辑和操作图像。要使用GD库根据颜色生成纯色背景图&#xff0c;可以按照以下步骤进行&#xff1a; 一、检查并安装GD库 检查GD库是否已安装&#xff1a; 可以通过运行phpinfo();或在命令行中使用p…...

Python 网络爬虫入门全知道

一、引言 在当今数字化时代&#xff0c;网络上的数据量呈爆炸式增长。无论是进行数据分析、市场调研&#xff0c;还是开发智能应用&#xff0c;获取网络数据都变得极为重要。而 Python 网络爬虫就是一把打开网络数据宝库的利器。它能够自动地从网页中抓取我们需要的信息&#…...

MATLAB期末复习笔记(下)

目录 五、数据和函数的可视化 1.MATLAB的可视化对象 2.二维图形的绘制 3.图形标识 4.多子图绘图 5.直方图的绘制 &#xff08;1&#xff09;分类 &#xff08;2&#xff09;垂直累计式 &#xff08;3&#xff09;垂直分组式 &#xff08;4&#xff09;水平分组式 &…...

基于大数据爬虫数据挖掘技术+Python的网络用户购物行为分析与可视化平台(源码+论文+PPT+部署文档教程等)

#1024程序员节&#xff5c;征文# 博主介绍&#xff1a;CSDN毕设辅导第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老…...

【go】只读通道和只写通道

文章目录 概述1. 通道的方向2. 为什么会有只读通道和只写通道&#xff1f;3. 总结 概述 在 Go 中&#xff0c;只读通道和只写通道的概念通过通道的方向来实现。Go 语言允许你在函数参数中指定通道的方向&#xff0c;从而限制通道的使用方式&#xff0c;这样可以确保代码的清晰…...

带Burst AOT Settings移植问题

报错 burst问题 Burst AOT Settings 是 Unity 的 Burst Compiler 的一部分&#xff0c;用于预编译程序集&#xff08;AOT&#xff0c;Ahead-Of-Time Compilation&#xff09;&#xff0c;以便在不支持 JIT&#xff08;即时编译&#xff09;的平台上运行&#xff0c;例如 iOS 和…...

Debezium日常分享系列之:Debezium Engine

Debezium日常分享系列之&#xff1a;Debezium Engine 依赖打包项目在代码中输出消息格式消息转换消息转换谓词高级记录使用引擎属性异步引擎属性数据库模式历史属性处理故障 Debezium连接器通常通过部署到Kafka Connect服务来运行&#xff0c;并配置一个或多个连接器来监视上游…...

运行 GreatSQL 时为什么要求关闭透明大页

在大部分运维规范中&#xff0c;一般都会要求在运行 GreatSQL/MySQL 的环境中要关闭透明大页&#xff0c;那么到底什么是透明大页&#xff0c;为什么要关闭&#xff0c;打开有什么风险吗&#xff1f; 在此之前&#xff0c;我也是有点懵的&#xff0c;本文试着回答这个疑问&…...

【Rive】Rive在Android上的简单应用

1 前言 Rive 是一款强大的矢量图编辑器&#xff0c;可以设计图形、也可以制作动画。Rive 提供了矩形、圆形、三角形、多边形、星形、钢笔、文字等工具来绘制各式各样的矢量图形&#xff1b;提供了平移、旋转、缩放等工具对矢量图形进行各种变换&#xff1b;提供了骨骼、约束、时…...

Base 崛起,SynFutures 或成生态系统中最具潜力应用

10月份的 Unchained Crypto 采访中&#xff0c;Solana 联合创始人 Anatoly 表示&#xff0c;通过观察活跃地址数、TVL、DeFi 版块、Meme 热潮和开发者生态等多个关键指标&#xff0c;察觉到 Base 势头正猛&#xff0c;成为以太坊生态最强劲的 L2。 11月下旬&#xff0c;小狐狸创…...

探索Go语言中的循环双向链表

简介 循环双向链表将双向链表的灵活性与循环结构相结合&#xff0c;使得每个节点都有一个指向前一个节点和后一个节点的指针&#xff0c;并且最后一个节点的Next指针指向头节点&#xff0c;形成一个闭环。本文将深入探讨如何在Go语言中实现和操作这种数据结构。 循环双向链表…...

Leetcode617.合并二叉树(HOT100)+Leetcode79. 单词搜索(HOT100)

链接 代码&#xff1a; class Solution { public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if(!root1)return root2;if(!root2)return root1;root1->valroot2->val;root1->left mergeTrees(root1->left,root2->left);root1->right merg…...

亚马逊云(AWS)使用root用户登录

最近在AWS新开了服务器&#xff08;EC2&#xff09;&#xff0c;用于学习&#xff0c;遇到一个问题就是默认是用ec2-user用户登录&#xff0c;也需要密钥对。 既然是学习用的服务器&#xff0c;还是想直接用root登录&#xff0c;下面开始修改&#xff1a; 操作系统是&#xff1…...

使用Docker在Ubuntu 22.04上部署MySQL数据库的完整指南

使用Docker在Ubuntu 22.04上部署MySQL数据库的完整指南 在现代应用开发中&#xff0c;使用Docker来部署数据库已成为一种流行的做法。本文将详细介绍如何在Ubuntu 22.04系统上使用Docker部署最新版本的MySQL数据库&#xff0c;包括关键注意事项、详细步骤、闭坑指南以及总结。…...

算法笔记:力扣15、三数之和

思路&#xff1a; 实现代码 class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result new ArrayList<>(); Arrays.sort(nums); // 先对数组进行排序 for (int i 0; i < nums.length - 2; i) { /…...

perf list PMU 缓存事件

事件标识事件解释PMU事件路径l1d_cacheL1数据缓存的访问次数&#xff0c;L1缓存是CPU内部最快的缓存&#xff0c;位于距离CPU核心非常近的位置。armv8_pmuv3/l1d_cache/l1d_cache_lmiss_rd表示从L1数据缓存读取数据时发生缓存未命中的次数。armv8_pmuv3/l1d_cache_lmiss_rd/l1d…...

使用C#开发VTK笔记(一)-VTK开发环境搭建

一.使用C#开发VTK的背景 因为C#开发的友好性,一直都比较习惯于从C#开发程序。而长期以来,都希望有一个稳定可靠的三位工程数模的开发演示平台,经过多次对比之后,感觉VTK和OpenCasCade这两个开源项目是比较好的,但它们都是用C++编写的,我用C#形式开发,只能找到发布的C#组…...

2024Selenium自动化常见问题!

"NoSuchElementException"异常&#xff1a; 确保使用了正确的选择器来定位元素。可以使用id、class、XPath或CSS选择器等。 可以尝试使用find_elements方法来查找元素列表&#xff0c;并检查列表的长度来判断元素是否存在。 使用显式等待&#xff08;WebDriverWait…...

考研英语翻译与大小作文

名词动化词 1 持有 harbor2 2 反映 mirror 3 缩短 bridge 4 使用 harness 5 掩饰 mask/veil 6 修改 tailor 7 汇集 pool 8 控制 curb 9 想象 picture 10 激发 trigger 拉丁…...