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

AWS codebuild + jenkins + github 实践CI/CD

前文

本文使用 Jenkins 结合 CodeBuild, CodeDeploy 实现 Serverless 的 CI/CD 工作流,用于自动化发布已经部署 lambda 函数。 在 AWS 海外区,CI/CD 工作流可以用 codepipeline 这项产品来方便的实现,

CICD 基本概念

  • 持续集成( Continuous Integration,简称CI ) 是指在应用代码的新组件集成到共享存储库之后自动测试和构建软件的流程。这样一来,就可以打造出始终处于工作状态的应用“版本”。
  • 持续交付( Continuous Deployment, 简称CD )是指将CI流程中创建的应用交付到类似生产环境的过程,在该过程中将对应用进行额外的自动化测试,以确保应用在部署到生产环境以及交付到真实用户手中时能够发挥预期作用。

架构综述

本文最终达到的效果为,源代码在 Github repo 中,每当有新的 commit,将自动触发 Jenkins CICD 工作流,Jenkin 会利用 CodeBuild 做构建,以及CodeDeploy 自动部署发布 lambda 新版本。

jenkins环境准备

jenkins EC2安装

先拉一个每月750小时免费的 EC2 实例t2.micro,  最后配置一个固定的弹性ip,后面如果时不时要用停止/启动EC2 实后ip不用再重复配置

登录EC2 安装jenkins,  我使用的是jenkins.war的方式部署为了避免jenkins 的使用环境上一些坑

jenkins.war的下载地址jenkins.war

安装jdk-17

更新OS
sudo yum update -y设置yum源
sudo wget -O /etc/yum.repos.d/jenkins.repo \https://pkg.jenkins.io/redhat-stable/jenkins.repo导入公钥
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key升级包
sudo yum upgrade安装java
sudo dnf install java-17-amazon-corretto -y

把jenkins.war放到/usr/local/jenkins 目录下,编辑 /etc/init.d/jenkins 作为启动脚本

#!/bin/bash# 在执行过程中若遇到使用了未定义的变量或命令返回值为非零,将直接报错退出
set -eu
# Default-Start: 2 3 4 5# 检查参数个数
if [ "${#}" -lt 1 ]; thenecho " 脚本使用示例: service jenkins start|stop|restart "exit
fi# 获取脚本第一个参数
APP_OPT=${1}
# 端口
APP_PORT=9001
# 名称
APP_NAME=jenkins
# jar名 | war名
APP_JAR=${APP_NAME}.war
# 程序根目录
APP_JAR_HOME=/usr/local/jenkins
# 日志名
APP_LOG_NAME=app-jenkins
# 日志根目录
APP_LOG_HOME=/usr/local/jenkins/log
# 程序运行参数
JAVA_OPTS="--httpPort=${APP_PORT}"echo "本次操作服务名:[${APP_NAME}]"
echo "本次操作选择:[${APP_OPT}]"# 停止
function stop(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... stop ..."# 查看该jar进程pid=`ps -ef | grep ${APP_NAME} | grep -v 'grep' | awk '{print $2}'`echo "[${APP_NAME}] pid="${pid}# 存在则kill,不存在打印一下吧if [ "${pid}" ]; thenkill -9 ${pid}# 检查kill是否成功if [ "$?" -eq 0 ]; thenecho "[${APP_NAME}] stop success"elseecho "[${APP_NAME}] stop fail"fielseecho "[${APP_NAME}] 进程不存在"fi
}# 运行
function start(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... start ..."cd ${APP_JAR_HOME}echo "当前路径:`pwd`"# 赋予可读可写可执行权限chmod 777 ${APP_JAR}echo "启动命令: nohup java -jar ${APP_JAR} ${JAVA_OPTS} >> ${APP_LOG_HOME}/${APP_LOG_NAME}.log 2>&1 &"sudo nohup java -jar ${APP_JAR} ${JAVA_OPTS} >> ${APP_LOG_HOME}/${APP_LOG_NAME}.log 2>&1 &if [ "$?" -eq 0 ]; thenecho "[${APP_NAME}] start success"elseecho "[${APP_NAME}] start fail"fi
}# 重启
function restart(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... restart ..."stopsleep 3start
}# 多分支条件判断执行参数
case "${APP_OPT}" in"stop")stop;;"start")start;;"restart")restart;;*)echo " 提示:不支持参数 命令 -> ${APP_OPT}";;
esac

jenkins工作目录磁盘空间挂载

因为我们使用的micro的EC2,  需要给jenkins 工作目录挂载更大的空间

Jenkins 默认是安装在/root/.jenkins 目录下,查看目录下使用和剩余空间

df -h /root/.jenkins/

将 /dev/nvme0n1p1 作为你的设备进行挂载并增加 /root/.jenkins 的空间,以下是相应的步骤: 步骤 1: 创建挂载点创建一个新的目录作为挂载点(例如 /mnt/jenkins_data):

sudo mkdir -p /mnt/jenkins_data

步骤 2: 挂载文件系统 将设备 /dev/nvme0n1p1 挂载到新创建的目录:

sudo mount /dev/nvme0n1p1 /mnt/jenkins_data

步骤 3: 更新 /etc/fstab 为了确保在重启后仍然保持挂载,需要更新 /etc/fstab 文件。打开该文件进行编辑:

sudo nano /etc/fstab

在文件末尾添加以下行:

/dev/nvme0n1p1 /mnt/jenkins_data ext4 defaults,nofail 0 2

确保根据实际文件系统类型(如 ext4)进行调整。 步骤 4: 移动 Jenkins 数据 如果 /root/.jenkins 中的数据需要迁移到新的挂载点:


sudo cp -r /root/.jenkins/* /mnt/jenkins_data/ sudo ln -s /mnt/jenkins_data /root/.jenkins

查看现在的工作空间大小

micro 免费的同时就得随时手动挂载确保空间足够,后面jenkins 交换空间不够也是这样解决的,

Dashboard -> 系统管理 -> 节点列表上, 如果资源不够是无法启动构建job的

启动jenkins

查看 Jenkins 初始密码

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

登录后安装必要的插件会花费一些时间

Github 准备

 创建一个项目类似于我做实践用的

https://github.com/chenrui2200/aws-jenkins-codepipeline

 develop setting 里生成token


 

保存该token后面会用到多次

配置webhooks

在项目内setting里配置webhooks ,  PayloadUrl 填写 <jenkins_url>/github-webhook/

点击保存

jenkins system configure 配置access token

把access token 录入到credentials

跳转system configuration

找到github server,  使用access token配置https://api.github.com

添加认证方式,在箭头处填写github access token

点击测试连接出现下面字样说明配置成功

项目文件准备

新建基于 python 的 lambda 函数。此 lambda 函数为我们的目标 lambda 函数,在本实验完成后,每当有新的 commit,都会触发此 lambda 函数进行自动化部署。 如您不清楚步骤,请参考创建您的第一个 Lambda 函数 此文重在搭建 CICD 流水线,代码会直接用默认生成的 python 代码 lambda_function.py。

publish 此 lambda,版本为1,并且创建别名(alias)。

除此以外,还需要添加另外两个文件

  • appspec.template.yaml, 用于 codedeploy 配置文件。请将此文件当中的函数名以及 alias(别名)替换为自己对应的值。
  • buildspec.yml,用于 codebuild 配置文件,修改替换文件中尖括号标注部分(去掉尖括号)。

buildspec.yml

version: 0.2phases:install:runtime-versions:python: 3.7commands:- echo pre Installing ...pre_build:commands:- echo prebuild,Installing update ...# 基本环境更新#- yum update -ybuild:commands:- echo Build started on `date`post_build:commands:- ls - mkdir build- # 替换所有尖括号标注,替换时,去掉尖括号- CurrentVersion=$(echo $(aws lambda get-alias --function-name <替换为自己的 lambda 函数 ARN> --name <替换为自己的lambda alias> --region <your_region> | grep FunctionVersion | tail -1 |tr -cd "[0-9]"))- zip -r ./build/lambda.zip ./lambda_function.py- aws lambda update-function-code --function-name <替换为自己的 lambda 函数 ARN> --zip-file fileb://build/lambda.zip  --region <your_region> --publish- TargetVersion=$(echo $(aws lambda list-versions-by-function --function-name <替换为自己的 lambda 函数 ARN> --region <your_region> | grep Version | tail -1 | tr -cd "[0-9]"))- echo $CurrentVersion- echo $TargetVersion- sed -e 's/{{CurrentVersion}}/'$CurrentVersion'/g' -e 's/{{TargetVersion}}/'$TargetVersion'/g' appspec.template.yaml > appspec.yaml- aws s3 cp appspec.yaml s3://<替换为自己的S3 Bucket名称>/jenkins/codedeploy/appspec.yaml- # 替换 first-try-with-jenkins 为自己的codedeploy名称- aws deploy create-deployment --application-name first-try-with-jenkins --deployment-group-name first-try-with-jenkins --s3-location bucket='<替换为自己的S3 Bucket名称>',key='jenkins/codedeploy/appspec.yaml',bundleType=YAML
artifacts:type: yamlfiles:- appspec.yaml

appspec.template.yaml

version: 0.0
Resources:- test: # Replace "MyFunction" with the name of your Lambda functionType: AWS::Lambda::FunctionProperties:Name: "test" # Specify the name of your Lambda functionAlias: "beta" # Specify the alias for your Lambda functionCurrentVersion: "{{CurrentVersion}}" # Specify the current version of your Lambda functionTargetVersion: "{{TargetVersion}}" # Specify the version of your Lambda function to deploy

lambda_function.py

import jsondef lambda_handler(event, context):# TODO implementreturn {'statusCode': 200,'body': json.dumps('Hello from Lambda!')}

AWS 准备

Codebuild 准备

新建codebuild项目

【源】选择github, 点击管理认证凭证配置访问凭证

认证成功

其他选项不用动

选择EC2 相同的vpc

使用buildspec文件构建,文件名对应的是github项目里的buildspec.yml 文件名称

codebuild选择的role需要具备 s3 codebuild的权限

CodeDeploy 准备

计算平台选择lamda

创建部署组组

codedeploy选择的role需要具备 codedeploy 的权限

构建CI/CD 流程

创建一个 Jenkin 的项目,配置 codedeploy 相应信息

新建项目之前,先安装 codebuild 的插件。点击 系统管理 -- 插件管理(plugin)

新建一Jenkins个项目,点击“Create a new project” -- "freestyle project"

配置Github项目的地址,源代码管理选择Git方式。

上面credentials没有显示secret text类别的,需要安装Plain Credentials Plugin。您还需要安装Credentials Binding Plugin来传递凭据, 同时宿主机上需要安装 git

触发构建,选择 Github hook trigger for GITScm polling

配置 AK, SK , region, project-name

尝试提交push下代码, 看到push事件已经触发了jenkins

jenkins端插件已经触发了codebuild 去构建,提交者是codebuild-jenkins plugin

整个流程已经打通, 查看jenkins 的构建日志

Codebuild 日志也看到成功了

查看lambda 函数已经成功更新了

有小伙伴反馈无法启动jenkins job出现下面错误

Dashboard ->  系统管理 ->  节点列表 下查看节点状态

增加/tmp 目录下磁盘空间, 使用/etc/fstab 扩展空间

[root@ip-10-0-13-218 ~]# sudo mount -t tmpfs -o size=2G tmpfs /tmp
[root@ip-10-0-13-218 ~]# echo "tmpfs /tmp tmpfs defaults,size=2G 0 0" | sudo tee -a /etc/fstab
tmpfs /tmp tmpfs defaults,size=2G 0 0
[root@ip-10-0-13-218 ~]# df -h /tmp/
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           2.0G     0  2.0G   0% /tmp

剩余交换空间不足问题通过下面命令解决

参考这篇帖子 Jenkins - Free Swap Space 0(剩余交换空间为0)_jenkins free swap space-CSDN博客

解决方式:

1、登陆服务器,查看swap,如下所示,没有配置swap

free|grep -i Swap
Swap:            0          0          0


 2、配置swap

dd if=/dev/zero of=swapfile bs=1M count=1K
mkswap swapfile
sudo chown root:root swapfile
sudo chmod 600 swapfile
sudo swapon swapfile


3、查看swap,配置成

free|grep -i Swap
Swap:      1048572          0    1048572

相关文章:

AWS codebuild + jenkins + github 实践CI/CD

前文 本文使用 Jenkins 结合 CodeBuild, CodeDeploy 实现 Serverless 的 CI/CD 工作流&#xff0c;用于自动化发布已经部署 lambda 函数。 在 AWS 海外区&#xff0c;CI/CD 工作流可以用 codepipeline 这项产品来方便的实现&#xff0c; CICD 基本概念 持续集成( Continuous…...

Android PMS(Package Manager Service)源码介绍

文章目录 前言一、PMS 启动流程二、APK 安装流程三、APK 卸载流程四、权限管理静态权限动态权限 五、 数据存储与一致性六、 PMS 的安全性策略1、权限检查2、签名认证3、动态权限管理4、应用安装验证5、保护系统目录 七、PMS 调试方法总结 前言 PackageManagerService&#xf…...

运维面试整理总结

面试题可以参考:面试题总结 查看系统相关信息 查看系统登陆成功与失败记录 成功&#xff1a;last失败&#xff1a;lastb 查看二进制文件 hexdump查看进程端口或连接 netstat -nltp ss -nltp补充&#xff1a;pidof与lsof命令 pidof [进程名] #根据 进程名 查询进程id ls…...

图数据库 Cypher语言

图数据库 属性图 属性图&#xff08;Property Graph&#xff09;概述 属性图是一种广泛用于建模关系数据的图数据结构&#xff0c;它将**顶点&#xff08;节点&#xff09;和边&#xff08;关系&#xff09;**进行结构化存储&#xff0c;并为它们附加属性以提供丰富的语义信…...

阿里云oss转发上线-实现不出网钓鱼

本地实现阿里云oss转发上线&#xff0c;全部代码在文末&#xff0c;代码存在冗余 实战环境 被钓鱼机器不出网只可访问内部网络包含集团oss 实战思路 若将我们的shellcode文件上传到集团oss上仍无法上线&#xff0c;那么就利用oss做中转使用本地转发进行上线&#xff0c;先发送…...

Spring Boot 3.4.0 发行:革新与突破的里程碑

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

【网络安全】

黑客入侵 什么是黑客入侵&#xff1f; “黑客”是一个外来词&#xff0c;是英语单词hacker的中文音译。最初&#xff0c;“黑客”只是一个褒义词&#xff0c;指的是那些尽力挖掘计算机程序最大潜力的点脑精英&#xff0c;他们讨论软件黑客的技巧和态度&#xff0c;以及共享文化…...

在SQLyog中导入和导出数据库

导入 假如我要导入一个xxx.sql&#xff0c;我就先创建一个叫做xxx的数据库。 然后右键点击导入、执行SQL脚本 选择要导入的数据库文件的位置&#xff0c;点击执行即可 注意&#xff1a; 导入之后记得刷新一下导出 选择你要导出的数据库 右键选择&#xff1a;备份/导出、…...

RabbitMQ简单应用

概念 RabbitMQ 是一种流行的开源消息代理&#xff08;Message Broker&#xff09;软件&#xff0c;它实现了高级消息队列协议&#xff08;AMQP - Advanced Message Queuing Protocol&#xff09;。RabbitMQ 通过高效的消息传递机制&#xff0c;主要应用于分布式系统中解耦应用…...

使用LUKS对Linux磁盘进行加密

前言 本实验用于日常学习用&#xff0c;如需对存有重要数据的磁盘进行操作&#xff0c;请做好数据备份工作。 此实验只是使用LUKS工具的冰山一角&#xff0c;后续还会有更多功能等待探索。 LUKS&#xff08;Linux Unified Key Setup&#xff09;是Linux系统中用于磁盘加密的一…...

戴尔电脑安装centos7系统遇到的问题

1&#xff0c;找不到启动盘&#xff08;Operation System Loader signature found in SecureBoot exclusion database(‘dbx’).All bootable devices failed secure Boot Verification&#xff09; 关闭 Secure Boot&#xff08;推荐&#xff09;&#xff1a; 进入 BIOS/UEFI…...

3.4.SynchronousMethodHandler组件之ResponseHandler

前言 feign发送完请求后, 拿到返回结果, 那么这个返回结果肯定是需要经过框架进一步处理然后再返回到调用者的, 其中ResponseHandler就是用来处理这个返回结果的, 这也是符合正常思维的处理方式, 例如springmvc部分在调用在controller端点前后都会增加扩展点。 从图中可以看得…...

Linux 下进程的状态

操作系统中常见进程状态 在操作系统中有六种常见进程状态: 新建状态: 进程正在被创建. 此时操作系统会为进程分配资源, 如: 内存空间等, 进行初始化就绪状态: 进程已经准备好运行了, 只需要等待被调度, 获取 CPU 资源就可以执行了, 操作系统中可能同时存在多个进程处于就绪状…...

【计算机网络】核心部分复习

目录 交换机 v.s. 路由器OSI七层更实用的TCP/IP四层TCPUDP 交换机 v.s. 路由器 交换机-MAC地址 链接设备和设备 路由器- IP地址 链接局域网和局域网 OSI七层 物理层&#xff1a;传输设备。原始电信号比特流。数据链路层&#xff1a;代表是交换机。物理地址寻址&#xff0c;交…...

Spring Boot开发实战:从入门到构建高效应用

Spring Boot 是 Java 开发者构建微服务、Web 应用和后端服务的首选框架之一。其凭借开箱即用的特性、大量的自动化配置和灵活的扩展性&#xff0c;极大简化了开发流程。本文将以实战为核心&#xff0c;从基础到高级&#xff0c;全面探讨 Spring Boot 的应用开发。 一、Spring B…...

pyshark安装使用,ubuntu:20.04

1.容器创建 命令 docker run -d --name pyshark -v D:\src:/root/share ubuntu:2004 /bin/bash -c "while true;do sleep 1000;done" 用于创建并启动一个新的 Docker 容器。 docker run -d --name pyshark -v D:\src:/root/share ubuntu:2004 /bin/bash -c "w…...

基本功能实现

目录 1、环境搭建 2、按键控制灯&电机 LED 电机 垂直按键(机械按键) 3、串口调试功能 4、定时器延时和定时器中断 5、振动强弱调节 6、万年历 7、五方向按键 1、原理及分析 2、程序设计 1、环境搭建 需求: 搭建一个STM32F411CEU6工程 分析: C / C 宏定义栏…...

《那个让服务器“跳舞”的bug》

在程序的世界里&#xff0c;bug 就像隐藏在暗处的小怪兽&#xff0c;时不时跳出来捣乱。而在我的职业生涯中&#xff0c;有一个bug让我至今难忘&#xff0c;它不仅让项目差点夭折&#xff0c;还让我熬了无数个通宵。这个故事发生在一个风和日丽的下午&#xff0c;我们正在开发一…...

Python 网络爬虫进阶:动态网页爬取与反爬机制应对

在上一篇文章中&#xff0c;我们学习了如何使用 Python 构建一个基本的网络爬虫。然而&#xff0c;在实际应用中&#xff0c;许多网站使用动态内容加载或实现反爬机制来阻止未经授权的抓取。因此&#xff0c;本篇文章将深入探讨以下进阶主题&#xff1a; 如何处理动态加载的网…...

创建可直接用 root 用户 ssh 登陆的 Docker 镜像

有时候我们在 Mac OS X 或 Windows 平台下需要开发以 Linux 为运行时的应用&#xff0c;IDE 或可直接使用 Docker 容器&#xff0c;或 SSH 远程连接。本地命令行下操作虽然可以用 docker exec 连接正在运行的容器&#xff0c;但 IDE 远程连接的话 SSH 总是一种较为通用的连接方…...

wordpress 中添加图片放大功能

功能描述 使用 Fancybox 实现图片放大和灯箱效果。自动为文章内容中的图片添加链接&#xff0c;使其支持 Fancybox。修改了 header.php 和 footer.php 以引入必要的 CSS 和 JS 文件。在 functions.php 中通过过滤器自动为图片添加 data-fancybox 属性。 最终代码 1. 修改 hea…...

数据结构 (7)线性表的链式存储

前言 线性表是一种基本的数据结构&#xff0c;用于存储线性序列的元素。线性表的存储方式主要有两种&#xff1a;顺序存储和链式存储。链式存储&#xff0c;即链表&#xff0c;是一种非常灵活和高效的存储方式&#xff0c;特别适用于需要频繁插入和删除操作的场景。 链表的基本…...

库的操作.

创建、删除数据库 创建语法&#xff1a; CREATE DATABASE [IF NOT EXISTS] db_name[ ]是可选项&#xff0c;IF NOT EXISTS 是表明如果不存在才能创建数据库 //查看数据库&#xff0c;假设7行 show databases; //创建数据库 --- 本质在Linux创建一个目录 create database databa…...

Vue进阶之Vue CLI服务—@vue/cli-service Vuex

Vue CLI服务—vue/cli-service & Vuex vue/cli-service初识bin/vue-cli-service.js代码执行解读 Vuexgenerator/index.jsstore/index.js插件化的能力怎么引入呢&#xff1f; vue/cli-service 初识 第一块是上一个讲述的cli是把我们代码的配置项&#xff0c;各种各样的插件…...

导入100道注会cpa题的方法,导入试题,自己刷题

一、问题描述 复习备考的小伙伴们&#xff0c;往往希望能够利用零碎的时间和手上的试题&#xff0c;来复习和备考 用一个能够导入自己试题的刷题工具&#xff0c;既能加强练习又能利用好零碎时间&#xff0c;是一个不错的解决方案 目前市面上刷题工具存下这些问题 1、要收费…...

数据库操作、锁特性

1. DML、DDL和DQL是数据库操作语言的三种主要类型 1.1 DML&#xff08;Data Manipulation Language&#xff09;数据操纵语言 DML是用于检索、插入、更新和删除数据库中数据的SQL语句。 主要的DML语句包括&#xff1a; SELECT&#xff1a;用于查询数据库中的数据。 INSERT&a…...

学习笔记039——SpringBoot整合Redis

文章目录 1、Redis 基本操作Redis 默认有 16 个数据库&#xff0c;使用的是第 0 个&#xff0c;切换数据库添加数据/修改数据查询数据批量添加批量查询删除数据查询所有的 key清除当前数据库清除所有数据库查看 key 是否存在设置有效期查看有效期 2、Redis 数据类型String追加字…...

(笔记)简单了解ZYNQ

1、zynq首先是一个片上操作系统&#xff08;Soc&#xff09;&#xff0c;结合了arm&#xff08;PS&#xff09;和fpga&#xff08;PL&#xff09;两部分组成 Zynq系统主要由两部分组成&#xff1a;PS&#xff08;Processing System&#xff09;和PL&#xff08;Programmable L…...

大众点评小程序mtgsig1.2算法

测试效果&#xff1a; var e function _typeof(o) {return "function" typeof Symbol && "symbol" typeof Symbol.iterator? function (o) {return typeof o;}: function (o) {return o && "function" typeof Symbol &…...

七牛云AIGC内容安全方案助力企业合规创新

随着人工智能生成内容(AIGC)技术的飞速发展,内容审核的难度也随之急剧上升。在传统审核场景中,涉及色情、政治、恐怖主义等内容的标准相对清晰明确,但在AIGC的应用场景中,这些界限变得模糊且难以界定。用户可能通过交互性引导AI生成违规内容,为审核工作带来了前所未有的不可预测…...

规避电子政务门户网站建设的教训/搜索关键词优化服务

更新日期&#xff1a;2018-11-5 微信bug&#xff1a; 在for循环中使用组件时&#xff0c;遮罩层成黑层. 更新时间 2018-9-30 2018-9-30  1.在电脑上调试input超出输入框范围会出现文字模糊以及位移现象&#xff08;手机端不影响&#xff09; index.wxml 1 <view class&qu…...

网站怎么做动态图片/企业推广方式有哪些

一、通用函数&#xff1a; colorbar 显示彩色条 语法&#xff1a;colorbar \ colorbar(vert) \ colorbar(horiz) \ colorbar(h) \ hcolorbar(...) \ colorbar(...,peer,axes_handle) getimage 从坐标轴取得图像数据 语法&#xff1a;Agetimage(h) \ [x,y,A]getimage(h) \ [...…...

威海市做网站的/南宁seo服务优化

这里讲下我从拿到新的Mac后怎么一步一步搭建Git环境的。 首先让我们打开终端 在终端输入 git 如果说你卡到下面的结果说明你没有安装个git&#xff0c;去安装。 The program git is currently not installed. You can install it by typing: sudo apt-get install git 如果你…...

wordpress怎么备案/温州seo公司

文章目录1、背景2、腾讯开放平台名片OCR接口2.1 文档参考2.2 小程序OCR功能主要JS代码实现3、微信小程序名片OCR功能接入3.1 微信小程序首页设计3.2 扫名片功能实现3.2.1 识别页面3.2.2 识别程序4 名片识别验证4.1 名片拍照4.2 名片识别1、背景 最近在做一个CRM微信小程序工具…...

建设什么网站/官网优化 报价

图论涉及的内容广泛&#xff0c;复杂&#xff0c;综合性较强。我在学习《算法竞赛进阶指南》图论部分后&#xff0c;为了方便日后复习让自己感觉学了东西&#xff0c;写下这篇大杂汇&#xff0c;内容主要源自我自己对《算法竞赛进阶指南》图论部分概括以及学习做题的经验。 一、…...

做管理培训的网站有什么/衡水seo培训

Python 大学生课表 iCalendar (.ics) 生成简介 大一新生第一次接触大学生课表&#xff0c;在有 Mac、iPhone 和 Apple Watch 设备的情况下希望能将自己的课表导入内置日历应用&#xff0c;以更方便的随时查看课表和规划行程。由于没有找到比较合适的 app 故自己写了这一代码。推…...