【Bond与你白话IaC之Terraform for Docker篇】 攻城狮如何向女友解释IaC呢?

news2024/11/23 23:48:57

前言:

       最近有机会与朋友聊到IaC(Infra as code)说到是否有比较好的切入点进行学习。
客观地说,看到XaX或XasX结构的的名词,让人立刻会与最前沿的云技术联系起来,但实际上其背后的思想仍然来自于传统系统的痛点与经验总结。IaC需要达到的目的就好像我们过去做过的这类事情:
       电脑城鼎盛时期: 我们用统一的ghost分区或者硬盘镜像去确保交付给顾客的电脑上操作系统与软件配置的严格统一性。可以帮助节省出货与售后成本。
       企业虚拟化时期: 我们利用VM为各种应用场景制作统一规范的VM模版,为横向与纵向扩展提供了一键部署特定VM的方式,极大提高部署效率与高度一致性。节省硬件与人力成本。
       容器技术时期: 我们利用自定义的docker image或者在k8s中,为企业内开发运维人员部署高度一致的pod与container,作为测试与UAT环境,同时借助dockerfile,迭代起来比VM更轻量级也更灵活。
       云上时期: 我们利用各家产品的管理组件,例如Azure中利用ARM(Azure Resource Manager)模版进行infra资源的部署,目的是为了避免环境不一致性与bug的不可复现性等等。

所有这些事情,其最后的作用都指向一个点:消除基础架构中的环境偏移问题。


        而这一点,就是IaC出现的初衷。它的优势包括但不限于:
1)通过更轻松地跟踪部署内容、时间和方式来促进审核。(换句话说,它提高了可跟踪性。)
2)在不同发布之间提供一致的环境。
3)提高开发、测试和生产环境之间的一致性。
4)自动化纵向扩展和横向扩展过程。
5)允许对配置进行版本控制。
6)提供代码评审和单元测试功能,帮助管理基础结构更改。
7)使用不可变服务进程,即如果需要对环境进行更改,则会部署新服务并移除旧服务,而不会更新服务。
8)允许蓝/绿部署。此发布方法可以将故障时间降至最低,其中存在两个相同的环境,一个是实时环境,另一个则不是。更新将应用于非实时服务器。验证并完成测试后,它将与不同的实时服务器进行交换。届时,该服务器将变成新的实时环境,而先前的实时环境不再是实时的。此方法也称为A/B部署。
9)将基础结构视为一种灵活的资源,可按需进行预配、取消预配和重新预配。

那么,攻城狮应该如何向女友解释IaC呢?
        从IaC的过程来举例:一个卖家想卖房,却不熟悉中间诸多法规与环节(备案,抵押,解押,面签,过户 等等等),也不敢自己全程操作。为了避免学习成本同时保证安全性,他会找到中介,因为他们会全权代理中间的所有步骤,而卖家只需要告诉其需求:价格与时限。 IaC就是那个中介。
        从IaC的结果来举例:A觉得B比自己优秀,通常A会默默观察B在服装,装扮,举止上的特点,并记在小本子上,认真模仿。当然现实中A有大概率还是成为不了B,但是IaC却可以,可以经由相同的过程得到完全一致的结果。

什么?你还是觉得难以理解? 那可能是因为你还没有一个攻城狮的男朋友 :P

IaC初体验之Terraform for Docker篇

好了,来看看入坑的初体验之 Docker篇。
Q1: 为什么是Docker?

A1:因为它免费呀,云账号很难找可以免费把玩的(试用期已用完)。过去借助VM,想学啥,就自己从零(指的是从裸机装OS开始)搭建的日子,受益匪浅,但是不适合云环境的学习了。

Q2: 为什么是Terraform?

A2: 开源,用的人多,因为它不局限于某一种云产品。


1.Overall Prerequisites

bond@BondMacProM1Pro terraform % terraform -version
Terraform v1.5.7
on darwin_arm64
bond@BondMacProM1Pro terraform % docker -v
Docker version 24.0.6, build ed223bc

bond@BondMacProM1Pro terraform % tree
.
├── bin
│   └── terraform
├── learn-terraform-docker-container
│   ├── main.tf
│   ├── outputs.tf
│   ├── terraform.tfstate
│   ├── terraform.tfstate.backup
│   └── variables.tf
└── terraform_note.txt

2.Initialize the directory for Demo project

 bond@BondMacProM1Pro learn-terraform-docker-container % cat main.tf

terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

provider "docker" {
  host="unix:///Users/bond/.docker/run/docker.sock"
}

resource "docker_image" "nginx" {
  name         = "nginx:latest"
  keep_locally = false
}

resource "docker_container" "nginx" {
  image = docker_image.nginx.image_id
  # name  = "tutorial"
  name = var.container_name
  ports {
    internal = 80
    external = 8080
  }
}

bond@BondMacProM1Pro learn-terraform-docker-container % cat variables.tf

variable "container_name" {
  description = "Value of the name for the Docker container"
  type        = string
  default     = "ExampleNginxContainer"
}

bond@BondMacProM1Pro learn-terraform-docker-container % cat outputs.tf

output "container_id" {
  description = "ID of the Docker container"
  value       = docker_container.nginx.id
}

output "image_id" {
  description = "ID of the Docker image"
  value       = docker_image.nginx.id
}

 

bond@BondMacProM1Pro learn-terraform-docker-container % terraform init

Initializing the backend...

Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "~> 3.0.1"...
- Installing kreuzwerker/docker v3.0.2...
- Installed kreuzwerker/docker v3.0.2 (self-signed, key ID BD080C4571C6104C)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

3.Format and validate the configuration

bond@BondMacProM1Pro learn-terraform-docker-container % terraform fmt
main.tf
bond@BondMacProM1Pro learn-terraform-docker-container % terraform validate
Success! The configuration is valid.


bond@BondMacProM1Pro learn-terraform-docker-container % docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT                              KUBERNETES ENDPOINT   ORCHESTRATOR
default             moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                                        
desktop-linux *     moby                Docker Desktop                            unix:///Users/bond/.docker/run/docker.sock    


provider "docker" {
  host="unix:///Users/bond/.docker/run/docker.sock"
}

 

4.Create infrastructure

bond@BondMacProM1Pro learn-terraform-docker-container % terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # docker_container.nginx will be created
  + resource "docker_container" "nginx" {
      + attach                                      = false
      + bridge                                      = (known after apply)
      + command                                     = (known after apply)
      + container_logs                              = (known after apply)
      + container_read_refresh_timeout_milliseconds = 15000
      + entrypoint                                  = (known after apply)
      + env                                         = (known after apply)
      + exit_code                                   = (known after apply)
      + hostname                                    = (known after apply)
      + id                                          = (known after apply)
      + image                                       = (known after apply)
      + init                                        = (known after apply)
      + ipc_mode                                    = (known after apply)
      + log_driver                                  = (known after apply)
      + logs                                        = false
      + must_run                                    = true
      + name                                        = "tutorial"
      + network_data                                = (known after apply)
      + read_only                                   = false
      + remove_volumes                              = true
      + restart                                     = "no"
      + rm                                          = false
      + runtime                                     = (known after apply)
      + security_opts                               = (known after apply)
      + shm_size                                    = (known after apply)
      + start                                       = true
      + stdin_open                                  = false
      + stop_signal                                 = (known after apply)
      + stop_timeout                                = (known after apply)
      + tty                                         = false
      + wait                                        = false
      + wait_timeout                                = 60

      + ports {
          + external = 8000
          + internal = 80
          + ip       = "0.0.0.0"
          + protocol = "tcp"
        }
    }

  # docker_image.nginx will be created
  + resource "docker_image" "nginx" {
      + id           = (known after apply)
      + image_id     = (known after apply)
      + keep_locally = false
      + name         = "nginx:latest"
      + repo_digest  = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

docker_image.nginx: Creating...
docker_image.nginx: Still creating... [10s elapsed]
docker_image.nginx: Creation complete after 11s [id=sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest]
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 1s [id=d5af79499d396a0f6f1e28b70ae53b62f73f1f28fdefb6483afed14b578f0422]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.


bond@BondMacProM1Pro learn-terraform-docker-container % docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    2a4fbb36e966   6 days ago   192MB

bond@BondMacProM1Pro learn-terraform-docker-container % docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS         PORTS                  NAMES
d5af79499d39   2a4fbb36e966   "/docker-entrypoint.…"   9 minutes ago   Up 9 minutes   0.0.0.0:8000->80/tcp   tutorial


bond@BondMacProM1Pro learn-terraform-docker-container % ls -lrt /Users/bond/Library/Containers/com.docker.docker/Data/vms/0/data
total 3902616
-rw-r--r--@ 1 bond  staff  80000057344  9 27 16:17 Docker.raw


5.Verify

visit to verify:   http://localhost:8000/

6.Inspect state

bond@BondMacProM1Pro learn-terraform-docker-container % terraform show
# docker_container.nginx:
resource "docker_container" "nginx" {
    attach                                      = false
    command                                     = [
        "nginx",
        "-g",
        "daemon off;",
    ]
    container_read_refresh_timeout_milliseconds = 15000
    cpu_shares                                  = 0
    entrypoint                                  = [
        "/docker-entrypoint.sh",
    ]
    env                                         = []
    hostname                                    = "d5af79499d39"
    id                                          = "d5af79499d396a0f6f1e28b70ae53b62f73f1f28fdefb6483afed14b578f0422"
    image                                       = "sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73"
    init                                        = false
    ipc_mode                                    = "private"
    log_driver                                  = "json-file"
    logs                                        = false
    max_retry_count                             = 0
    memory                                      = 0
    memory_swap                                 = 0
    must_run                                    = true
    name                                        = "tutorial"
    network_data                                = [
        {
            gateway                   = "172.17.0.1"
            global_ipv6_address       = ""
            global_ipv6_prefix_length = 0
            ip_address                = "172.17.0.2"
            ip_prefix_length          = 16
            ipv6_gateway              = ""
            mac_address               = "02:42:ac:11:00:02"
            network_name              = "bridge"
        },
    ]
    network_mode                                = "default"
    privileged                                  = false
    publish_all_ports                           = false
    read_only                                   = false
    remove_volumes                              = true
    restart                                     = "no"
    rm                                          = false
    runtime                                     = "runc"
    security_opts                               = []
    shm_size                                    = 64
    start                                       = true
    stdin_open                                  = false
    stop_signal                                 = "SIGQUIT"
    stop_timeout                                = 0
    tty                                         = false
    wait                                        = false
    wait_timeout                                = 60

    ports {
        external = 8000
        internal = 80
        ip       = "0.0.0.0"
        protocol = "tcp"
    }
}

# docker_image.nginx:
resource "docker_image" "nginx" {
    id           = "sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest"
    image_id     = "sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73"
    keep_locally = false
    name         = "nginx:latest"
    repo_digest  = "nginx@sha256:32da30332506740a2f7c34d5dc70467b7f14ec67d912703568daff790ab3f755"
}


bond@BondMacProM1Pro learn-terraform-docker-container % terraform state list
docker_container.nginx
docker_image.nginx

7.Update configuration

Change the docker_container.nginx resource under the provider block in main.tf by replacing the ports.external value of 8000 with 8080

7.1 Check change plan

bond@BondMacProM1Pro learn-terraform-docker-container % terraform plan
docker_image.nginx: Refreshing state... [id=sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest]
docker_container.nginx: Refreshing state... [id=d5af79499d396a0f6f1e28b70ae53b62f73f1f28fdefb6483afed14b578f0422]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # docker_container.nginx must be replaced
-/+ resource "docker_container" "nginx" {
      + bridge                                      = (known after apply)
      ~ command                                     = [
          - "nginx",
          - "-g",
         ...............................
         ...............................

      - tmpfs                                       = {} -> null
        # (14 unchanged attributes hidden)

      ~ ports {
          ~ external = 8000 -> 8080 # forces replacement
            # (3 unchanged attributes hidden)
        }
    }

Plan: 1 to add, 0 to change, 1 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.


7.2 Implement change

bond@BondMacProM1Pro learn-terraform-docker-container % terraform apply
docker_image.nginx: Refreshing state... [id=sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest]
docker_container.nginx: Refreshing state... [id=d5af79499d396a0f6f1e28b70ae53b62f73f1f28fdefb6483afed14b578f0422]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # docker_container.nginx must be replaced
-/+ resource "docker_container" "nginx" {
      + bridge                                      = (known after apply)
      ~ command                                     = [
          - "nginx",
          - "-g",

        ...............................
        ...............................

      ~ stop_timeout                                = 0 -> (known after apply)
      - storage_opts                                = {} -> null
      - sysctls                                     = {} -> null
      - tmpfs                                       = {} -> null
        # (14 unchanged attributes hidden)

      ~ ports {
          ~ external = 8000 -> 8080 # forces replacement
            # (3 unchanged attributes hidden)
        }
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

docker_container.nginx: Destroying... [id=d5af79499d396a0f6f1e28b70ae53b62f73f1f28fdefb6483afed14b578f0422]
docker_container.nginx: Destruction complete after 0s
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 0s [id=9c7f7fb0fb52ad18652b6d12eb32fe008aca27e5b88509c12c863892bb65064a]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.


bond@BondMacProM1Pro learn-terraform-docker-container % docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS         PORTS                  NAMES
9c7f7fb0fb52   2a4fbb36e966   "/docker-entrypoint.…"   4 minutes ago   Up 4 minutes   0.0.0.0:8080->80/tcp   tutorial

8.Destroy infrastructure

bond@BondMacProM1Pro learn-terraform-docker-container % terraform destroy
docker_image.nginx: Refreshing state... [id=sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest]
docker_container.nginx: Refreshing state... [id=9c7f7fb0fb52ad18652b6d12eb32fe008aca27e5b88509c12c863892bb65064a]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # docker_container.nginx will be destroyed
  - resource "docker_container" "nginx" {
      - attach                                      = false -> null
      - command                                     = [
          - "nginx",
        ...............................
        ...............................
    

  # docker_image.nginx will be destroyed
  - resource "docker_image" "nginx" {
      - id           = "sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest" -> null
      - image_id     = "sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73" -> null
      - keep_locally = false -> null
      - name         = "nginx:latest" -> null
      - repo_digest  = "nginx@sha256:32da30332506740a2f7c34d5dc70467b7f14ec67d912703568daff790ab3f755" -> null
    }

Plan: 0 to add, 0 to change, 2 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

docker_container.nginx: Destroying... [id=9c7f7fb0fb52ad18652b6d12eb32fe008aca27e5b88509c12c863892bb65064a]
docker_container.nginx: Destruction complete after 0s
docker_image.nginx: Destroying... [id=sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest]
docker_image.nginx: Destruction complete after 0s

Destroy complete! Resources: 2 destroyed.


bond@BondMacProM1Pro learn-terraform-docker-container % docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES


9.Define input variables

Terraform configurations can include variables to make your configuration more dynamic and flexible.
Note:Terraform loads all files in the current directory ending in .tf, so you can name your configuration files however you choose.

Create a new file called variables.tf with a block defining a new container_name variable.

In main.tf, update the docker_container resource block to use the new variable. The container_name variable block will default to its default value ("ExampleNginxContainer") unless you declare a different value.

resource "docker_container" "nginx" {
  image = docker_image.nginx.image_id
  # name  = "tutorial"
  name = var.container_name
  ports {
    internal = 80
    external = 8080
  }
}


bond@BondMacProM1Pro learn-terraform-docker-container % terraform apply
docker_image.nginx: Refreshing state... [id=sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest]
docker_container.nginx: Refreshing state... [id=baea93480dc7e21d938c3fdf8e7f4a7124c76b981ab28f44daf44584fa327258]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # docker_container.nginx must be replaced
-/+ resource "docker_container" "nginx" {
        ...............................
        ...............................   

Plan: 1 to add, 0 to change, 1 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

docker_container.nginx: Destroying... [id=baea93480dc7e21d938c3fdf8e7f4a7124c76b981ab28f44daf44584fa327258]
docker_container.nginx: Destruction complete after 0s
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 0s [id=694e4020413e7d3837ef69159d7ba9e2ac2f6aa824bfbf45e6b6c04150e81543]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Now apply the configuration again, this time overriding the default container name by passing in a variable using the -var flag. Terraform will update the container's name attribute with the new name.
bond@BondMacProM1Pro learn-terraform-docker-container % terraform apply -var "container_name=YetAnotherName"

bond@BondMacProM1Pro learn-terraform-docker-container % terraform show
.........
    name = "YetAnotherName"
.........


bond@BondMacProM1Pro learn-terraform-docker-container % docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED              STATUS              PORTS                  NAMES
d8dc60162e03   2a4fbb36e966   "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp   YetAnotherName

bond@BondMacProM1Pro learn-terraform-docker-container % terraform apply
.........
Plan: 1 to add, 0 to change, 1 to destroy.

Changes to Outputs:
  + container_id = (known after apply)
  + image_id     = "sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest"
.........


10.The output comes from terraform show

bond@BondMacProM1Pro learn-terraform-docker-container % terraform output     
container_id = "995c0dc8afdfd32e0cbd389444e45910f59027d155efd29fe5851988e5e5e841"
image_id = "sha256:2a4fbb36e96607b16e5af2e24dc6a1025a4795520c98c6b9ead9c4113617cb73nginx:latest"

#### End ####

后记:

1.可以发现IaC实际上是一个概念与方法论,具体实现需要依靠响应的产品,例如Terraform或者ARM等等。

2.针对不同的后端云产品,Docker,Azure,AWS,AliYun,GCP 等,主流的IaC工具均进行了适配,为每一类资源定义了可调整的配置接口。

3.有没有一种感觉,IaC确实降低了直接操作后端产品的门槛,例如:使用者并不需要知道如何run一个docker image并且按照需求暴露端口给guest。

4. 总的来说,还是一种高效(偷懒)的运维工具,客户们最喜欢了。

5. 如果你即使没有攻城狮的男朋友,也大致明白了什么是IaC,那就太棒了!

                                                                                                See you!

                                                                                       2023年9月28日  

                                                                                       祝大家明天中秋快乐!国庆快乐!

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

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

相关文章

python web编程一:token、session、cookie、密码加解密

1 认证 1 传统的session-cookie机制 HTTP协议是无状态协议,为了解决它产生了cookie和session技术。 浏览器发起第一次请求到服务器,服务器发现浏览器没有提供session id,就认为这是第一次请求,会返回一个新的session id给浏览器…

Flask扩展:简化开发的利器以及26个日常高效开发的第三方模块(库/插件)清单和特点总结

目录 寻找扩展 使用扩展 创建扩展 26个常用的Flask扩展模块 总结 原文:Flask扩展:简化开发的利器以及26个日常高效开发的第三方模块(库/插件)清单和特点总结 (qq.com) Flask是一个轻量级的Python Web框架,它提供…

14.(开发工具篇github)如何在Github配置ssh key

第一步:检查本地主机是否已经存在ssh key 上图表示已存在。跳第三步 第二步:生成ssh key ssh-keygen -t rsa -C "xxxxxx.com"第三步:获取ssh key公钥内容(id_rsa.pub) cat id_rsa.pub第四步:G…

如何将图片转为ico格式

这里主要是记录一个网站,如果你有更好的办法欢迎留言~ ico简介 ICO(Icon)是一种用于表示图标的文件格式,常用于Windows操作系统中。ICO格式的图片通常用于表示应用程序、文件夹、网站等的图标。 ICO文件可以包含多个图标&#x…

在 .NET 8 Release Candidate 1 中推出 .NET MAUI:质量

作者:David Ortinau 排版:Alan Wang 今天,我们很高兴地宣布 .NET MAUI 在 .NET 8 Release Candidate 1 中已经可用,该版本带有适用于生产应用程序的正式许可证,因此您可以放心地将此版本用于生产环境。我们在 .NET 8 中…

用代码打造未来教育:在线教育平台开发的奇妙之旅

当我们谈论在线教育平台开发时,我们正在谈论一项颠覆性的技术,它改变了传统教育的面貌。在线教育已经成为21世纪的教育主题,使学习变得更加灵活、便捷和个性化。本文将探讨在线教育平台开发的关键方面,并穿插一些代码示例来帮助您…

wordpress插件-免费的wordpress全套插件

在当今数字化时代,网站和博客已经成为信息传递、观点分享和商业交流的重要平台。在这个背景下,WordPress作为最受欢迎的内容管理系统之一,无疑扮演着至关重要的角色。然而,要保持一个成功的WordPress网站,不仅需要出色…

不要二(牛客)

目录 一、题目 二、代码 一、题目 不要二__牛客网 二、代码 采用贪心算法的思想来做,开始全置为1,1代表放入蛋糕。 从左向右从上到下遍历棋盘开始依此放蛋糕,然后将该块蛋糕上下左右欧几里得距离为2的点全部标记为0,表示该点不…

泛函分析(一)

目录 1.数学基本概念 2.泛函概念和应用 2.1常用知识点 2.2泛函数解决的问题 2.3核函数 3.应用 参考文献 1.数学基本概念 2.泛函概念和应用 2.1常用知识点 算子:无限维空间到无限维空间的变换称为。泛函数:就是函数的函数,即一般函数自…

二、C++项目:仿muduo库实现并发服务器之时间轮的设计

文章目录 一、为什么要设计时间轮?(一)简单的秒级定时任务实现:(二)Linux提供给我们的定时器:1.原型2.例子 二、时间轮(一)思想(一)代码 一、为什…

基于SpringBoot网上超市的设计与实现【附万字文档(LW)和搭建文档】

主要功能 前台登录: 注册用户:用户名、密码、姓名、联系电话 用户: ①首页、商品信息推荐、商品资讯、查看更多 ②商品信息、商品详情、评论、点我收藏、添加购物车、立即购买 ③个人中心、余额、点我充值、更新信息、我的订单、我的地址、我…

国庆出游,景区该怎么接住这泼天的流量?媒介媒介盒子告诉你

国庆出游,景区该怎么接住这泼天的流量?媒介媒介盒子告诉你 假期倒计时。这一次,几亿人又要大规模出游了,景区最不愁的,就是没有流量。那么景区该怎么接住这泼天的流量呢? 1、利用社交媒体营销。 利用微信…

26591-2011 粮油机械 糙米精选机

声明 本文是学习GB-T 26591-2011 粮油机械 糙米精选机. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了糙米精选机的有关术语和定义、工作原理、型号及基本参数、技术要求、试验方法、检 验规则、标志、包装、运输和储存要求。 …

5+预后模型+实验验证

今天给同学们分享一篇SUMO化修饰预后模型实验验证的生信文章“The Prognosis-Predictive and Immunoregulatory Role of SUMOylation Related Genes: Potential Novel Targets in Prostate Cancer Treatment”,这篇文章于2023年9月2日发表在Int J Mol Sci期刊上&…

YTM32的DMA控制器要点详解

YTM32的DMA控制器要点详解 文章目录 YTM32的DMA控制器要点详解引言简介原理与机制DMA通道的传输任务描述符DMA的触发信号DMA的大循环和小循环DMA搬运任务的地址更新策略 应用要点(软件)参考文献 引言 考虑到DMA是一个AHB Master设备,可以同处…

蛋白质科学中的人工智能

蛋白质在初级水平上由一系列氨基酸链组成。它们可以折叠成3D结构,以执行许多生物功能。最近在图神经网络、扩散模型和3D几何建模方面的突破使得机器学习可以加速发现新蛋白质。在这一部分,我们将重点关注蛋白质科学中的三个人工智能主题,包括…

【算法练习Day8】 kmp算法找出字符串中第一个匹配项的下标反转字符串中的单词重复的子字符串

、​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 kmp算法找出字符串中第…

MySQL学习笔记21

MySQL逻辑备份: mysqldump基本备份: 本质:导出的是sql语句文件。 优点:无论是什么存储引擎,都可以用mysqldump备份成sql语句。 缺点:速度较慢,导入的时候出现格式不兼容的突发情况&#xff…

Appium开发

特点 开源免费支持多个平台 IOS(苹果)、安卓App的自动化都支持 支持多种类型的自动化 支持苹果、安卓应用原生界面的自动化支持应用内嵌网络视图的自动化支持手机浏览器(Chrome)中的web网站自动化支持flutter应用的自动化 支持多种编程语言 像selenium一样,可以用多…

全面解读 SQL 优化 - 统计信息

一、简介 数据库中的优化器(optimizer)是一个重要的组件,用于分析 SQL 查询语句,并生成执行计划。在生成执行计划时,优化器需要依赖数据库中的统计信息来估算查询的成本,从而选择最优的执行计划。以下是关…