APISIX安装与灰度、蓝绿发布

news2024/12/23 6:25:28

文章目录

    • 1、安装
      • 1.1、基于docker安装
      • 1.2、基于RPM安装
    • 2、灰度发布与蓝绿发布测试
      • 2.1、compose安装nginx
        • 2.1.1、创建目录
        • 2.1.2、编辑nginx.conf配置文件
        • 2.1.3、编辑docker-compose.yml文件
        • 2.1.4、启动nginx
      • 2.2、部署apisix和apisix-dashboard
      • 2.3、traffic-split插件实现灰度和蓝绿发布
      • 2.3.1、灰度发布
      • 2.3.2、蓝绿发布

1、安装

安装教程:https://apisix.apache.org/zh/docs/apisix/installation-guide/

1.1、基于docker安装

# 下载
git clone https://github.com/apache/apisix-docker.git
cd apisix-docker/example

#启动
docker compose -p docker-apisix up -d

1.2、基于RPM安装

# 安装etcd
ETCD_VERSION='3.5.4'
wget https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
tar -xvf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz && \
  cd etcd-v${ETCD_VERSION}-linux-amd64 && \
  sudo cp -a etcd etcdctl /usr/bin/
nohup etcd >/tmp/etcd.log 2>&1 &

# 安装 OpenResty仓库
yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm
# 安装 APISIX 的 RPM 仓库:
yum-config-manager --add-repo https://repos.apiseven.com/packages/centos/apache-apisix.repo
# 安装 APISIX
yum install apisix-2.13.1

#APISIX 安装完成后,你可以运行以下命令初始化 NGINX 配置文件和 etcd:
apisix init
#启动 APISIX
apisix start

2、灰度发布与蓝绿发布测试

三台虚拟机:

服务器ip应用
m1192.168.28.133apisix(网关)
s1192.168.28.136nginx(web服务)
s2192.168.28.132nginx(web服务)

s1、s2机器作为负载机器,完全灰度和蓝绿发布的测试机器。

2.1、compose安装nginx

s1和s2两台机器负责提供web服务,两台机器都通过docker安装nginx。安装配置如下。

2.1.1、创建目录

mkdir -p /home/nginx/www /home/nginx/logs /home/nginx/conf
vi /home/nginx/www/index.html

# index.html内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>docker测试</title>
</head>
<body>
    <h1>nginx正在运行</h1>
</body>
</html>

2.1.2、编辑nginx.conf配置文件

vi /home/nginx/conf/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
    
    server{
       listen 80;
       server_name localhost;
       charset utf-8;

       location / {
          root   /usr/share/nginx/html/;
          try_files $uri $uri/ =404;
          index  index.html index.htm;
       }
       
       #error_page  404              /404.html;

       # redirect server error pages to the static page /50x.html
       #
       error_page   500 502 503 504  /50x.html;
       location = /50x.html {
           root   html;
       }
    }
}

2.1.3、编辑docker-compose.yml文件

docker-compose.yml配置说明:https://docs.docker.com/compose/compose-file/
vi /home/nginx/docker-compose.yml

version: '3.3'
services:
      nginx:
        image: nginx
        restart: always
        hostname: nginx
        container_name: nginx
        privileged: true
        ports:
          - 9081:80
        volumes:
          - ./conf/nginx.conf:/etc/nginx/nginx.conf
          - ./www/:/usr/share/nginx/html/
          - ./logs/:/var/log/nginx/

2.1.4、启动nginx

# 启动
$ docker compose up -d
# 停止
$ docker compose down 

s1访问
在这里插入图片描述
s2访问
在这里插入图片描述

2.2、部署apisix和apisix-dashboard

使用https://github.com/apache/apisix-docker的docker compose部署模板
相关配置文件
/usr/local/apisix-docker/apisix_conf/config.yaml

apisix:
  node_listen: 9080              # APISIX listening port
  enable_ipv6: false

  enable_control: true
  control:
    ip: "0.0.0.0"
    port: 9092

deployment:
  admin:
    allow_admin:               # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow
      - 0.0.0.0/0              # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.

    admin_key:
      - name: "admin"
        key: edd1c9f034335f136f87ad84b625c8f1
        role: admin                 # admin: manage all configuration data

      - name: "viewer"
        key: 4054f7cf07e344346cd3f287985e76a2
        role: viewer

  etcd:
    host:                           # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
      - "http://etcd:2379"          # multiple etcd address
    prefix: "/apisix"               # apisix configurations prefix
    timeout: 30                     # 30 seconds

plugin_attr:
  prometheus:
    export_addr:
      ip: "0.0.0.0"
      port: 9091

/usr/local/apisix-docker/dashboard_conf/conf.yaml

conf:
  listen:
    host: 0.0.0.0     # `manager api` listening ip or host name
    port: 9000          # `manager api` listening port
  allow_list:           # If we don't set any IP list, then any IP access is allowed by default.
    - 0.0.0.0/0
  etcd:
    endpoints:          # supports defining multiple etcd host addresses for an etcd cluster
      - "http://etcd:2379"
                          # yamllint disable rule:comments-indentation
                          # etcd basic auth info
    # username: "root"    # ignore etcd username if not enable etcd auth
    # password: "123456"  # ignore etcd password if not enable etcd auth
    mtls:
      key_file: ""          # Path of your self-signed client side key
      cert_file: ""         # Path of your self-signed client side cert
      ca_file: ""           # Path of your self-signed ca cert, the CA is used to sign callers' certificates
    # prefix: /apisix     # apisix config's prefix in etcd, /apisix by default
  log:
    error_log:
      level: warn       # supports levels, lower to higher: debug, info, warn, error, panic, fatal
      file_path:
        logs/error.log  # supports relative path, absolute path, standard output
                        # such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr
    access_log:
      file_path:
        logs/access.log  # supports relative path, absolute path, standard output
                         # such as: logs/access.log, /tmp/logs/access.log, /dev/stdout, /dev/stderr
                         # log example: 2020-12-09T16:38:09.039+0800	INFO	filter/logging.go:46	/apisix/admin/routes/r1	{"status": 401, "host": "127.0.0.1:9000", "query": "asdfsafd=adf&a=a", "requestId": "3d50ecb8-758c-46d1-af5b-cd9d1c820156", "latency": 0, "remoteIP": "127.0.0.1", "method": "PUT", "errs": []}
authentication:
  secret:
    secret              # secret for jwt token generation.
                        # NOTE: Highly recommended to modify this value to protect `manager api`.
                        # if it's default value, when `manager api` start, it will generate a random string to replace it.
  expire_time: 3600     # jwt token expire time, in second
  users:                # yamllint enable rule:comments-indentation
    - username: admin   # username and password for login `manager api`
      password: admin
    - username: user
      password: user

plugins:                          # plugin list (sorted in alphabetical order)
  - api-breaker
  - authz-keycloak
  - basic-auth
  - batch-requests
  - consumer-restriction
  - cors
  # - dubbo-proxy
  - echo
  # - error-log-logger
  # - example-plugin
  - fault-injection
  - grpc-transcode
  - hmac-auth
  - http-logger
  - ip-restriction
  - jwt-auth
  - kafka-logger
  - key-auth
  - limit-conn
  - limit-count
  - limit-req
  # - log-rotate
  # - node-status
  - openid-connect
  - prometheus
  - proxy-cache
  - proxy-mirror
  - proxy-rewrite
  - redirect
  - referer-restriction
  - request-id
  - request-validation
  - response-rewrite
  - serverless-post-function
  - serverless-pre-function
  # - skywalking
  - sls-logger
  - syslog
  - tcp-logger
  - udp-logger
  - uri-blocker
  - wolf-rbac
  - zipkin
  - server-info
  - traffic-split

/usr/local/apisix-docker/etcd_conf/etcd.conf.yml

# Human-readable name for this member.
name: 'default'
# Path to the data directory.
data-dir:
# Path to the dedicated wal directory.
wal-dir:
# Number of committed transactions to trigger a snapshot to disk.
snapshot-count: 10000
# Time (in milliseconds) of a heartbeat interval.
heartbeat-interval: 100
# Time (in milliseconds) for an election to timeout.
election-timeout: 1000
# Raise alarms when backend size exceeds the given quota. 0 means use the
# default quota.
quota-backend-bytes: 0
# List of comma separated URLs to listen on for peer traffic.
listen-peer-urls: http://localhost:2380
# List of comma separated URLs to listen on for client traffic.
listen-client-urls: http://localhost:2379
# Maximum number of snapshot files to retain (0 is unlimited).
max-snapshots: 5
# Maximum number of wal files to retain (0 is unlimited).
max-wals: 5
# Comma-separated white list of origins for CORS (cross-origin resource sharing).
cors:
# List of this member's peer URLs to advertise to the rest of the cluster.
# The URLs needed to be a comma-separated list.
initial-advertise-peer-urls: http://localhost:2380
# List of this member's client URLs to advertise to the public.
# The URLs needed to be a comma-separated list.
advertise-client-urls: http://localhost:2379
# Discovery URL used to bootstrap the cluster.
discovery:
# Valid values include 'exit', 'proxy'
discovery-fallback: 'proxy'
# HTTP proxy to use for traffic to discovery service.
discovery-proxy:
# DNS domain used to bootstrap initial cluster.
discovery-srv:
# Initial cluster configuration for bootstrapping.
initial-cluster:
# Initial cluster token for the etcd cluster during bootstrap.
initial-cluster-token: 'etcd-cluster'
# Initial cluster state ('new' or 'existing').
initial-cluster-state: 'new'
# Reject reconfiguration requests that would cause quorum loss.
strict-reconfig-check: false
# Accept etcd V2 client requests
enable-v2: true
# Enable runtime profiling data via HTTP server
enable-pprof: true
# Valid values include 'on', 'readonly', 'off'
proxy: 'off'
# Time (in milliseconds) an endpoint will be held in a failed state.
proxy-failure-wait: 5000
# Time (in milliseconds) of the endpoints refresh interval.
proxy-refresh-interval: 30000
# Time (in milliseconds) for a dial to timeout.
proxy-dial-timeout: 1000
# Time (in milliseconds) for a write to timeout.
proxy-write-timeout: 5000
# Time (in milliseconds) for a read to timeout.
proxy-read-timeout: 0
client-transport-security:
  # Path to the client server TLS cert file.
  cert-file:
  # Path to the client server TLS key file.
  key-file:
  # Enable client cert authentication.
  client-cert-auth: false
  # Path to the client server TLS trusted CA cert file.
  trusted-ca-file:
  # Client TLS using generated certificates
  auto-tls: false

peer-transport-security:
  # Path to the peer server TLS cert file.
  cert-file:
  # Path to the peer server TLS key file.
  key-file:
  # Enable peer client cert authentication.
  client-cert-auth: false
  # Path to the peer server TLS trusted CA cert file.
  trusted-ca-file:
  # Peer TLS using generated certificates.
  auto-tls: false

# Enable debug-level logging for etcd.
debug: false
logger: zap
# Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
log-outputs: [stderr]
# Force to create a new one member cluster.
force-new-cluster: false
auto-compaction-mode: periodic
auto-compaction-retention: "1"

prometheus和grafana配置省略

/usr/local/apisix-docker/docker-compose.yml

version: "3"
services:
  apisix-dashboard:
    image: apache/apisix-dashboard:2.13-alpine
    restart: always
    volumes:
    - ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
    ports:
    - "9000:9000"
    networks:
      apisix:

  apisix:
    image: apache/apisix:3.0.0-debian
    restart: always
    volumes:
      - ./apisix_log:/usr/local/apisix/logs
      - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
    depends_on:
      - etcd
    ##network_mode: host
    ports:
      - "9180:9180/tcp"
      - "9080:9080/tcp"
      - "9091:9091/tcp"
      - "9443:9443/tcp"
      - "9092:9092/tcp"
    networks:
      apisix:

  etcd:
    image: bitnami/etcd:3.4.15
    restart: always
    volumes:
      - etcd_data:/bitnami/etcd
    environment:
      ETCD_ENABLE_V2: "true"
      ALLOW_NONE_AUTHENTICATION: "yes"
      ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
      ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
    ports:
      - "2379:2379/tcp"
    networks:
      apisix:

  prometheus:
    image: prom/prometheus:v2.25.0
    restart: always
    volumes:
      - ./prometheus_conf/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    networks:
      apisix:

  grafana:
    image: grafana/grafana:7.3.7
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - "./grafana_conf/provisioning:/etc/grafana/provisioning"
      - "./grafana_conf/dashboards:/var/lib/grafana/dashboards"
      - "./grafana_conf/config/grafana.ini:/etc/grafana/grafana.ini"
    networks:
      apisix:

networks:
  apisix:
    driver: bridge

volumes:
  etcd_data:
    driver: local

启动

cd /usr/local/apisix-docker
# 启动
$ docker compose up -d
# 停止
$ docker compose down 

在这里插入图片描述

2.3、traffic-split插件实现灰度和蓝绿发布

官方教程:https://apisix.apache.org/zh/docs/apisix/plugins/traffic-split/

2.3.1、灰度发布

通过weighted_upstreams的weight属性来实现流量分流。按 1:9 的权重流量比例进行划分,其中10%的流量到达运行在s1服务器,90%的流量到达运行在s2服务器。

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/*",
    "name": "route_gray",
    "plugins": {
        "traffic-split": {
            "rules": [
                {
                    "weighted_upstreams": [
                        {
                            "upstream": {
                                "name": "s1",
                                "type": "roundrobin",
                                "nodes": {
                                    "192.168.28.136:9081":10
                                },
                                "timeout": {
                                    "connect": 15,
                                    "send": 15,
                                    "read": 15
                                }
                            },
                            "weight": 1
                        },
                        {
                            "weight": 9
                        }
                    ]
                }
            ]
        }
    },
    "upstream": {
            "name": "s2",
            "type": "roundrobin",
            "nodes": {
                "192.168.28.132:9081": 1
            }
    }
}'

浏览器访问
在这里插入图片描述

2.3.2、蓝绿发布

在新功能发布时,线上环境临时变为蓝绿环境。新功能先发在蓝色环境(s1服务器)更新,并且限定客户端IP=192.168.28.132才能访问。

curl http://127.0.0.1:9180/apisix/admin/routes/2 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/*",
    "name": "route_blue",
    "plugins": {
        "traffic-split": {
            "rules": [
                {
                    "match": [
                        {
                            "vars": [
                                ["remote_addr","==","192.168.28.132"]
                            ]
                        }
                    ],
                    "weighted_upstreams": [
                        {
                            "upstream": {
                                "name": "s2",
                                "type": "roundrobin",
                                "nodes": {
                                    "192.168.28.132:9081":10
                                }
                            }
                        }
                    ]
                }
            ]
        }
    },
    "upstream": {
            "name": "s1",
            "type": "roundrobin",
            "nodes": {
                "192.168.28.136:9081": 1
            }
    }
}'

curl访问
curl http://192.168.28.133:9080/index.html
在这里插入图片描述

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

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

相关文章

【能效管理】安科瑞远程预付费系统在江西某沃尔玛收费管理的应用

摘要&#xff1a;文章根据用电远程管控原理&#xff0c;设计了用电预付费远程管理终端及管理系统&#xff0c;该系统以智能远程预付费电表、智能网关以及预付费管理软件实现了商业综合体的用电管理&#xff0c;实现了欠费自动分闸&#xff0c;充值后自动合闸&#xff0c;并辅助…

我用diffusion把姐妹cos成了灭霸的模样

卷友们好&#xff0c;我是rumor。关注早的朋友们应该知道&#xff0c;我有个姐妹&#xff0c;她去年回深圳老家了&#xff0c;本来我觉得还ok&#xff0c;还能再约着一起旅游。谁知道一年多了&#xff0c;我还没出过北京&#xff08;微笑。以前有个快乐源泉&#xff0c;就是照她…

谈谈Vue项目打包的方式

目录 一、相关配置 情况一&#xff08;使用的工具是 vue-cil&#xff09; 情况二&#xff08;使用的工具是 webpack&#xff09; 二、打包 &#x1f4da; 参考资料 这篇文章主要为大家介绍了Vue项目的打包方式&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴…

[附源码]计算机毕业设计基于springboot的低碳生活记录网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

1.3 Apache Hadoop的重要组成-hadoop-最全最完整的保姆级的java大数据学习资料

文章目录1.3 Apache Hadoop的重要组成1.3 Apache Hadoop的重要组成 HadoopHDFS(分布式文件系统)MapReduce(分布式计算框架)Yarn(资源协调框架)Common模块 Hadoop HDFS&#xff1a;&#xff08;Hadoop Distribute File System &#xff09;一个高可靠、高吞吐量的分布式文件系统…

mongodb整合springbootQ

SpringBoot整合MongoDB_一个冬天的童话的博客-CSDN博客_mongodb的依赖SpringBoot整合MongoDB的过程https://blog.csdn.net/m0_53563908/article/details/1268980981&#xff0c;环境配置 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId&g…

吉莱微电子IPO被终止:曾拟募资8亿 李建新父子是大股东

雷递网 雷建平 12月2日江苏吉莱微电子股份有限公司&#xff08;简称&#xff1a;“吉莱微电子”&#xff09;日前在深交所IPO被终止。吉莱微电子曾计划募资8亿元。其中&#xff0c;4.08亿用于功率半导体器件产业化建设项目&#xff0c;1.78亿用于生产线技改升级项目&#xff0c…

TCP/IP 网络嗅探器开发实例

主要内容 实例使用环境 知识储备 IP数据报格式 IP头结构体定义 TCP头格式 TCP头结构体定义 实例的调用演示 实例的完整代码 initsock.h protoinfo.h文件 Sniffer.cpp文件 实例总结 基于原始套接字的网络封包嗅探的工作过程 Sniffer节点调用分析 在Visual Studio2…

[附源码]计算机毕业设计基于springboot的高校车辆租赁管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

组合设计模式

一、组合模式 1、定义 组合模式&#xff08;Composite Pattern&#xff09;又称作整体-部分&#xff08;Part-Whole&#xff09;模式&#xff0c;其宗旨是通过将单个对象&#xff08;叶子节点&#xff09;和组织对象&#xff08;树枝节点&#xff09;用相同的接口进行表示&…

Egg 1. 快速开始 Quick Start 1.3 一步步 Step by Step 1.3.6 添加扩展 ~ 1.4 结论

Egg Egg 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录Egg1. 快速开始 Quick Start1.3 一步步 Step by Step1.3.6 添加扩展1.3.7 添加中间件1.3.8 添加配置1.3.9 添加单元测试1.4 结论1. 快速开始 Quick Start 1.3 一步步 Step by Step 1.3.…

求矩阵的行列式和逆矩阵 det()和inv()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 求矩阵的行列式和逆矩阵 det()和inv() [太阳]选择题 请问对以下Python代码说法错误的是&#xff1f; import numpy as np A np.array([[0,1],[2,3]]) print ("【显示】矩阵A") pr…

HedgeDoc的反向代理设置

因为 HedgeDoc 支持协同&#xff0c;所以很大可能性需要做反向代理设置&#xff0c;来让更多的人参与&#xff0c;但在上文 『Markdown协作编辑平台HedgeDoc』 中&#xff0c;老苏并未涉及到这部分&#xff0c;本文就是做这方面的补充。 老苏只研究了 nginx proxy manager 做反…

22个Vue 源码中的工具函数

前言 在 vue 源码中&#xff0c;封装了很多工具函数&#xff0c;学习这些函数&#xff0c;一方面学习大佬们的实现方式&#xff0c;另一方面是温习基础知识&#xff0c;希望大家在日常工作中&#xff0c;简单的函数也可以自己封装&#xff0c;提高编码能力。 本次涉及的工具函…

力扣(LeetCode)130. 被围绕的区域(C++)

dfs 只有和边界相连的 OOO 不会被 XXX 包围。遍历边界&#xff0c;搜索边界 OOO 的连通块&#xff0c;标记这些连通块。最后一次遍历矩阵&#xff0c;将标记的格子改回 OOO &#xff0c;其他格子改成 XXX &#xff0c;即为所求。 提示 : 可以用数组标记连通块&#xff0c;也可…

Java基于springboot+vue药店实名制买药系统 前后端分离

开发背景和意义 药品一直以来在人类生活中扮演着非常重要的角色&#xff0c;随着时代的发展&#xff0c;人们基本已经告别了那个缺医少药的年代&#xff0c;各大药房基本随处可以&#xff0c;但是很多时候因为没有时间或者在药店很难找到自己想要购买的药品&#xff0c;所以很…

元宇宙产业委叶毓睿:狂欢过后,万众期待的元宇宙怎么样了?

叶毓睿&#xff08;王学民/摄&#xff09; 自元宇宙出现在大众视野&#xff0c;大众对元宇宙的好奇和探索&#xff0c;从来没有停止过。当元宇宙的热度逐渐下降&#xff0c;我们不禁想要知道&#xff0c;狂欢过后&#xff0c;万众期待的元宇宙怎么样了&#xff1f; 近日&#x…

【吴恩达机器学习笔记】十一、聚类

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为学习吴恩达机器学习视频的同学提供的随堂笔记。 &#x1f4da;专栏简介&#xff1a;在这个专栏&#xff0c;我将整理吴恩达机器学习视频的所有内容的笔记&…

算法刷题入门线性表|单调栈

一、概念 1、栈的定义 栈 是仅限在 一端 进行 插入 和 删除 的 线性表。 栈 又被称为 后进先出 (Last In First Out) 的线性表&#xff0c;简称 LIFO 。 2、栈顶 栈 是一个线性表&#xff0c;我们把允许 插入 和 删除 的一端称为 栈顶。 3、栈底 和 栈顶 相对&#xff0c;另一端…

java计算机毕业设计ssm软件学院社团管理系统l62lq(附源码、数据库)

java计算机毕业设计ssm软件学院社团管理系统l62lq&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#…