【云原生网关】apisix使用详解

news2024/11/13 15:17:57

目录

一、apisix介绍

1.1 apisix是什么

二、apisix特点

2.1 多平台支持

2.2 全动态能力

2.3 精细化路由

2.4 对运维友好

2.5 多语言支持

三、apisix优势

3.1 apisix生态全景图

3.2 apisix定位

3.3 apisix优点

3.4 与nginx对比

四、apisix应用场景

4.1 Load Balancer 和 API 网关

4.2 微服务网关

4.3 Kubernetes Ingress

4.4 服务网格

五、apisix架构解读

5.1 数据面

5.2 控制面

5.3 apisix的重要组件和概念

六、apisix安装

6.1 docker-compose 环境准备

6.1.1 下载docker-compose文件

6.1.2 添加可执行权限

6.1.3 检查版本

6.2  apisix安装步骤

6.2.1 获取安装包

6.2.2 解压安装包

6.2.3 启动容器

6.2.4 开启相关端口

6.2.5 WEB-UI访问控制台

七、apisix路由配置

7.1 Admin API 路由配置

7.1.1 Admin API 简介

7.1.2 Admin API Route使用

7.2 apisix与微服务整合

7.2.1 准备一个springboot工程

7.2.2 添加一个测试用的接口

7.2.3 打包并上传服务器

7.2.4 启动服务并测试接口

7.2.5 配置apisix

7.2.6 使用新的规则访问

7.2.7 负载均衡配置

八、apisix控制台dashboard使用

8.1 自定义路由配置

 8.1.2 配置过程

8.1.3 测试验证

九、apisix整合nacos实现服务发现

9.1 部署nacos的server服务

9.2 搭建springboot工程,整合nacos

9.2.1 pom依赖

9.2.2 添加配置文件

9.2.3 添加测试接口

9.2.4 启动类

9.2.5 打包并上传服务器

9.2.6 启动服务

9.3 配置apisix路由规则

9.3.1 apisix配置nacos

9.3.2 dashboard配置路由规则

9.3.3 测试验证

十、写在结尾


一、apisix介绍

1.1 apisix是什么

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关,提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。可以使用 Apache APISIX 处理传统的南北向流量,也可以处理服务间的东西向流量。同时,它也支持作为 k8s IngressController 来使用。官方文档:apisix文档

Apache APISIX 可以帮助企业快速、安全地处理 API 和微服务流量,比如限流认证、日志安全功能,以及支持丰富的自定义插件。目前也与很多开源项目如 Apache SkyWalking、Prometheus 等之类的组件进行了相关集成。

二、apisix特点

说到apisix,作为一款与云原生生态紧密结合的API网关,很难抛开nginx这个负载均衡组件,相比传统的负载均衡服务器,apisix也有自己的特性。

2.1 多平台支持

APISIX 提供了多平台解决方案,它不但支持裸机运行,也支持在 Kubernetes 中使用,还支持与 AWS Lambda、AzureFunction、Lua 函数和 Apache OpenWhisk 等云服务集成。

2.2 全动态能力

APISIX 支持热加载,这意味着你不需要重启服务就可以更新 APISIX 的配置。

2.3 精细化路由

APISIX 支持使用 NGINX 内置变量做为路由的匹配条件,你可以自定义匹配函数来过滤请求,匹配路由。

2.4 对运维友好

APISIX 支持与以下工具和平台集成:HashiCorp Vault、Zipkin、Apache SkyWalking、Consul、Nacos、Eureka。通过 APISIXDashboard,运维人员可以通过友好且直观的 UI 配置 APISIX。

2.5 多语言支持

APISIX 支持多种开发语言进行插件开发,开发人员可以选择擅长语言的 SDK 开发自定义插件。

三、apisix优势

3.1 apisix生态全景图

从生态图不难看出,apisix依托云原生的优势,在整个生态体系下占据着非常重要的地位。

3.2 apisix定位

全流量网关(南北、东西)

3.3 apisix优点

结合apisix自身的特点以及生态全景,这里对apisix的突出优点做一个小结,以备后续架构技术选型参考:

1、摆脱了对数据库依赖;

2、云原生友好,与k8s生态关系密切;

3、支持多语言插件,不同插件之间也支持实时的动态编排;

4、支持集群管理和动态加载;

5、全流量网关(南北、东西);

6、多服务发现组件;

7、云与混合云场景探索;

     1)上下游均支持 mTLS;

     2)控制面与数据面架构完全分离;

     3)加强安全管理;

     4)集成更多云上标准;

3.4 与nginx对比

可以这么讲,只要聊到网关基本上很难抛开nginx不谈,毕竟nginx经过这么多年的发展,可以说几乎是互联网公司的标配产品了。在单体服务时代,使用 NGINX 可以应对大多数的场景,而到了云原生时代,NGINX 因为其自身架构的原因则会出现两个问题:

  • 首先是 NGINX 不支持集群管理,几乎每家互联网厂商都有自己的NGINX 配置管理系统,系统虽然大同小异但是一直没有统一的方案;
  • 其次是 NGINX 不支持配置的热加载,很多公司一旦修改了配置,重新加载 NGINX 的时间可能需要半个小时以上;

在 Kubernetes 体系下,上游会经常发生变化,如果使用 NGINX 来处理就需要频繁重启服
务,这对于企业是不可接受的。

四、apisix应用场景

APISIX 的核心是高性能代理服务,自身不绑定任何环境属性。当它演变为Ingress、服务网格等产品时,都是外部服务与 APISIX 配合,变化的是外部程序而不是 APISIX 自身,下面将逐步为大家介绍 APISIX 是如何支持这些场景的。

4.1 Load Balancer 和 API 网关

首先是针对传统的 LB 和 API 网关场景,因为 APISIX 基于 NGINX + LuaJIT 实现,所以天然具备高性能、安全等特性,并且原生支持了动态 SSL 证书卸载、SSL 握手优化等功能,在负载均衡的服务能力上也更优秀。

从 NGINX 切换到APISIX 不仅性能不会下降,而且可以享受到动态、统一管理等特性带来的管理效率的提升。

4.2 微服务网关

APISIX 目前支持多种语言编写扩展插件,可以解决东西向微服务 API 网关面临的主要问题——异构多语言和通用问题。内置支持的服务注册中心有 Nacos、etcd、Eureka 等,还有标准的 DNS 方式,可以平滑替代 Zuul、Spring CloudGateway、Dubbo 等微服务 API 网关。

4.3 Kubernetes Ingress

目前 K8s 官方 Kubernetes Ingress Controller 项目主要基于 NGINX 配置文件的方式,所以在路由能力和加载模式上稍显不足,并且存在一些明显劣势。比如添加、修改任何 API 时,需要重启服务才能完成新 NGINX 配置的更新,但重启服务,对线上流量的影响是非常大的。而 APISIX Ingress Controller 则完美解决了上面提到的所有问题:支持全动态,无需重启加载。同时继承了 APISIX 的所有优势,还支持原生 KubernetesCRD,方便用户迁移。

4.4 服务网格

未来五到十年,基于云原生模式架构下的服务网格架构开始崭露头角。APISIX也提前开始锁定赛道,通过调研和技术分析后,APISIX 已经支持了 xDS 协议,APISIX Mesh 就此诞生,在服务网格领域 APISIX 也拥有了一席之地。

五、apisix架构解读

apisix的架构如下图所示

结合上图,不难发现,APISIX 的架构主要分成两部分:数据面和控制面。

5.1 数据面

它是真正去处理来自客户端请求的一个组件,去处理用户的真实流量,包括像身份验证、证书卸载、日志分析和可观测性等功能。数据面本身并不会存储任何数据,所以它是一个无状态结构。

5.2 控制面

使用etcd而非传统的关系型数据库,更贴合云原生,API网关存放的数据类型,具有高可用性,低于毫秒级别的变化通知。

APISIX 在底层架构上和其它 API 网关的一个很大不同就在于控制面。APISIX 在控制面上并没有使用传统的类似于像 MySQL 去做配置存储,而是选择使用 etcd。这样做的好处主要有以下几点:

  • 与产品架构的云原生技术体系更统一;
  • 更贴合 API 网关存放的数据类型;
  • 能更好地体现高可用特性;
  • 拥有低于毫秒级别的变化通知;

使用 etcd 后,对于数据面而言只需监听 etcd 的变化即可。如果轮询数据库的话,可能需要 5-10 秒才能获取取到最新的配置;但如果监听 etcd 的配置变更,就可以将时间控制在毫秒级别之内,达到实时生效的效果。

5.3 apisix的重要组件和概念

在真正开始深入学习apisix之前,需要了解一下apisix中的几个重要概念和组件

概念/组件详细描述
Route通过路由定义规则来匹配客户端请求,根据匹配结果加载并执行相应的插件,最后把请求转发给到指定的上游应用。
Upstream上游的作用是按照配置规则对服务节点进行负载均衡,它的地址信息可以直接配置到路由或服务上。
Admin API用户可以通过 Admin API 控制 APISIX 实例

六、apisix安装

apisix支持裸机安装或容器安装,官方建议使用容器化安装,一方面是部署简单方便,同时对资源的消耗相对较少,下面演示如何使用docker的方式部署apisix;

6.1 docker-compose 环境准备

6.1.1 下载docker-compose文件

curl -SL https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

6.1.2 添加可执行权限

chmod +x /usr/local/bin/docker-compose

6.1.3 检查版本

docker-compose --version

6.2  apisix安装步骤

6.2.1 获取安装包

通过 git 命令克隆 apisix-docker 仓库:

git clone git@github.com:apache/apisix‐docker.git
cd apisix‐docker/example

如果git下载速度比较慢的话,也可以使用下面的地址进行下载

wget http://manongbiji.oss-cn-beijing.aliyuncs.com/ittailkshow/sca2023/download/apisix-docker-master.zip -O apisix-docker-master.zip

6.2.2 解压安装包

unzip apisix-docker-master.zip

6.2.3 启动容器

进入example目录,执行如下docker-compose命令启动相关容器的服务

cd example

docker‐compose ‐f docker-compose.yml up ‐d

执行过程如下: 

6.2.4 开启相关端口

请确保其他系统进程没有占用 9080、9180、9443 和 2379 端口,云服务器的话需要开放这几个端口。

6.2.5 WEB-UI访问控制台

如果容器都能正常启动运行起来,apisix提供了web的控制台,访问地址:http://IP:9000,默认登录用户密码admin/admin;

登录进去之后如下展示效果,可以根据自身的需要在这里进行路由相关的设置;

七、apisix路由配置

apisix提供了动态灵活的路由功能,可以通过 Admin API 或者 Dashboard 进行配置。

Admin API文档地址:官方文档

7.1 Admin API 路由配置

7.1.1 Admin API 简介

Admin API 是一组用于配置 Apache APISIX 路由、上游、服务、SSL 证书等功能的 RESTful API。你可以通过 Admin API 来获取、创建、更新以及删除资源。同时得益于 APISIX 的热加载能力,资源配置完成后 APISIX 将会自动更新配置,无需重启服务。如果你想要了解其工作原理,请参考 Architecture Design。

7.1.2 Admin API Route使用

Route 也称之为路由,可以通过定义一些规则来匹配客户端的请求,然后根据匹配结果加载并执行相应的插件,并把请求转发给到指定 Upstream(上游)。

使用下面的代码,我们将为路由配置匹配规则,以便 APISIX 可以将请求转发到对应的上游服务:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
    "methods": ["PUT", "GET"],
    "hosts": ["example.com"],
    "uri": "/anything/*",
    "enable_websocket": true,
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "httpbin.org:80": 1
        }
    }
}'

配置说明

当满足以下所有规则的时候,请求将被转发到上游服务:

  • 请求方法类型为PUT或GET;
  • 请求头包含 host 字段,且它的值为 example.com;
  • 请求路径匹配 /anything/*,* 意味着任意的子路径,例如 /anything/foo?arg=10;

执行上面的路由创建规则,看到下面的提示说明路由规则已经创建

可以通过以下命令访问上游服务:

 curl -i -X GET "http://127.0.0.1:9080/anything/foo?arg=10" -H "Host: example.com"

输出如下结果

对于路由中的参数配置,可以结合apisix配置手册 中的Route模块的配置说明进行理解,里面提供了非常丰富的示例可以参考,主要是在工作过程中遇到了具体使用场景时,能够快速查阅即可。

7.2 apisix与微服务整合

接下来使用一个实际的案例,即简单模拟一个微服务的业务场景,使用apisix配置如何访问到微服务中的接口。

7.2.1 准备一个springboot工程

结构如下

7.2.2 添加一个测试用的接口

@RestController
public class ProductController {

    @GetMapping("/product/{id}")
    public Object getById(@PathVariable("id") Integer id){
        Map<String,Object> result = new HashMap();
        result.put("id",id);
        result.put("name","商品");
        result.put("server-port","8083");
        return result;
    }

}

7.2.3 打包并上传服务器

本地打完包之后,可以上传到服务器任意位置

7.2.4 启动服务并测试接口

可以直接使用java -jar 即可启动服务,启动成功后可以通过浏览器访问一下该接口,可以看到输出如下信息(注意:需要提前在服务器配置JDK环境,同时需要开发相关的端口)

7.2.5 配置apisix

执行下面的命令进行路由规则的创建,具体的参数配置含义结合文档参考,其实和nginx很类似;

curl http://120.55.95.42:9180/apisix/admin/routes/2 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
    "methods": ["GET"],
    "hosts": ["Host,一般是外部浏览器访问的域名地址,测试时可以直接使用外网IP"],
    "uri": "/p/*",
    "plugins": {
        "proxy-rewrite": {
            "regex_uri":[ 
                "/p/(.*)",
                "/$1"
               ]
        }
    },

    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "路由到的后台服务地址,即上游服务,域名或IP:端口(端口默认不填监听80)": 1(权重值)
        }
    }
}'

然后在shell控制台执行一下,看到下面的信息,说明创建成功

也可以登录到控制台,看到上面创建的这条路由配置规则信息;

7.2.6 使用新的规则访问

根据上面的规则,当我们访问的接口地址中以 /p 开始时,将直接路由到8083端口的服务上,可以看到下面的效果;

7.2.7 负载均衡配置

现在假如要配置一个负载均衡的业务场景该怎么做呢,我们现在再开启一个服务,端口为8085

即现在同时存在8083和8085对应的两个相同的服务,只需要配置upstream相关参数即可,执行下面的命令进行规则的创建;

curl http://IP:9180/apisix/admin/routes/2 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
    "methods": ["GET"],
    "hosts": ["IP"],
    "uri": "/p/*",
    "plugins": {
        "proxy-rewrite": {
            "regex_uri":[ 
                "/p/(.*)",
                "/$1"
               ]
        }
    },

    "upstream": {
        "type": "roundrobin",
        "nodes":[{"host":"IP", "port":8083, "weight": 1},{"host":"IP", "port":8085, "weight": 8}]
    }
}'

主要,创建完毕这个配置规则后,建议先删除之前的配置规则,避免测试时看不到效果

按照上面的配置可以知道,8085这个端口将会有更多几乎杯访问到,配置完成后,再次访问接口,在多次反复的访问中,8085被访问到的次数更多;

八、apisix控制台dashboard使用

apisix提供了一个dashboard控制台可以方便开发运维在界面上进行路由规则的配置,上面当启动docker-compose之后,控制台就开启并可以直接访问了。

Apache APISIX Dashboard 是基于浏览器的可视化平台,用于监控、管理Apache APISIX。Apache APISIX Dashboard 可以让用户尽可能直观、便捷地通过可视化界面操作 Apache APISIX。通过 Dashboard,我们能够:

  • 创建并管理 服务、上游、路由、应用、证书、全局插件等模块;
  • 配合内置的80多种插件,可精细化控制流量;
  • 支持配置自定义插件;
  • 围绕 API 全生命周期管理提供解决方案,通过持续地更新、升级,更好地为用户赋能;
  • 兼容 OpenAPI 3.0,支持路由的导入、导出;

8.1 自定义路由配置

接下来演示下如何基于dashboard配置一下路由规则,,仍以上文的两个不同端口的服务为例进行说明。

 8.1.2 配置过程

点击路由配置创建

填写下面的主要路由信息即可

像使用命令创建一样,进入到这个页面后,给其中一个端口的服务配置更高的权重;

 

后面的可以保持默认即可,配置完成后在路由列表就可以看到上面的配置了

8.1.3 测试验证

访问下面的接口地址,反复多刷几次接口,效果和上面差不多,8085端口的服务有更多的几乎被访问到;

九、apisix整合nacos实现服务发现

nacos是springcloud-alibaba微服务生态体系下非常重要的组件,常作为服务注册和发现使用。使用注册中心可以实现服务生产者和消费者的解耦。

Apache APISIX + Nacos 可以将各个微服务节点中与业务无关的各项控制,集中在Apache APISIX 中进行统一管理,即通过 Apache APISIX 实现接口服务的代理和路由转发的能力。在 Nacos 上注册各个微服务后,Apache APISIX 可以通过 Nacos 的服务发现功能获取服务列表,查找对应的服务地址从而实现动态代理。

使用apisix对nacos实现路由配置的工作原理流程如下图所示,apisix在相当于是起到了一个服务接口的代理和路由转发功能;

接下来使用一个实际的案例来完成apisix整合nacos实现服务发现的步骤;

9.1 部署nacos的server服务

官网下载一个nacos的server端的压缩包,解压后,进入到bin目录,直接使用下面的命令启动即可

./startup.sh -m standalone

启动完成后,开发8848端口,浏览器可以访问nacos的控制台,查看相关的服务或配置信息

9.2 搭建springboot工程,整合nacos

为了模拟接近真实的效果,这里需要准备一个springboot工程,与nacos进行整合

9.2.1 pom依赖

主要是nacos相关的依赖

   <packaging>jar</packaging>

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/>
    </parent>

    <!-- 统一管理jar包版本 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <log4j.version>1.2.17</log4j.version>
    </properties>

    <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--nacos-config 配置中心-自带动态刷新-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <!--nacos-discovery 注册中心-服务发现与注册-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

9.2.2 添加配置文件

在application.yaml配置如下内容

server:
  port: 8085

spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: nacos IP:8848 #服务注册中心地址
      #config:
        #server-addr: localhost:8848 #配置中心地址

9.2.3 添加测试接口

@RestController
public class NacosController {

    @GetMapping("/user/info")
    public Object getObjectInfo(){
        Map<String,Object> result = new HashMap<>();
        result.put("username","jerry");
        result.put("age","28");
        return result;
    }

}

9.2.4 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class BootApp {
    public static void main(String[] args) {
        SpringApplication.run(BootApp.class,args);
    }

}

9.2.5 打包并上传服务器

9.2.6 启动服务

使用java -jar命令启动服务,启动完成后,在nacos的控制台的服务列表中可以看到nacos-provider服务已经成功进行注册;

可以通过浏览器调用接口,测试服务接口是否可正常使用;

到这里,前置准备工作就已经完成,接下来就需要进行apisix相关的路由配置即可;

9.3 配置apisix路由规则

9.3.1 apisix配置nacos

在example目录下,进入 example/apisix_conf/config.yaml 文件,然后添加如下配置

discovery:
  nacos:
    host:
      - "http://nacos IP:8848"

配置完成退出之后一定要重启docker服务

# 重启工程中所有服务的容器
docker-compose restart


# 重启工程中指定服务容器
docker-compose restart 容器名称

9.3.2 dashboard配置路由规则

这里分为两步,第一步配置上游服务,第二步配置路由规则

配置上游服务

参照下面的信息进行填写配置

配置完成后在列表中就可以看到了

配置路由规则

添加一个新的路由规则,第一张图配置一下路由的路径

 第二张图主要配置关联上游服务信息,后面的暂时使用默认的即可;

配置完成之后在路由列表就可以看到上面的配置规则了

9.3.3 测试验证

浏览器通过apisix的方式访问一下,看到下面的效果,说明使用apisix的方式整合成功

十、写在结尾

本文通过较大的篇幅,全面阐述了apisix这一款云原生 API 网关的使用,从安装,配置到使用,通过实际的使用体验能够感受到,云原生的崛起已经势在必行,可编程,可配置的网关必定会成为云原生与微服务架构体系中一个不错的结合点,有必要对这个网关做深入的了解和学习。

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

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

相关文章

设计模式-结构型模式之桥接模式

2. 桥接模式2.1. 模式动机设想如果要绘制矩形、圆形、椭圆、正方形&#xff0c;我们至少需要4个形状类&#xff0c;但是如果绘制的图形需要具有不同的颜色&#xff0c;如红色、绿色、蓝色等&#xff0c;此时至少有如下两种设计方案&#xff1a;第一种设计方案是为每一种形状都提…

Python 基础(七):常用运算符

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录一、算术运算符二、按位运算符2.1 按位与 &2.2 按位或 |2.3 按位异或 ^2.4 按位取反…

Three.js教程:顶点颜色数据插值计算

推荐&#xff1a;将 NSDT场景编辑器 加入你3D工具链 其他工具系列&#xff1a; NSDT简石数字孪生 顶点颜色数据插值计算 上节课自定义几何体给大家介绍了一个顶点位置坐标概念&#xff0c;本节课给大家介绍一个新的几何体顶点概念&#xff0c;就是几何体顶点颜色。 通常几何体…

python学习笔记(二)IF、FOR、WHILE、break、continue、函数定义与调用、面向对象

笔记二 流程控制if条件语句for循环语句while循环语句break 和continue python 函数定义与调用函数与调用函数的脚本分离脚本模板函数参数匿名参数变量作用域全局变量与局部变量 python面向对象类的创建实例的创建属性、方法的访问属性的添加、删除和修改属性的访问python内置类…

( “树” 之 前中后序遍历 ) 144. 二叉树的前序遍历 ——【Leetcode每日一题】

基础概念&#xff1a;前中后序遍历 1/ \2 3/ \ \ 4 5 6层次遍历顺序&#xff1a;[1 2 3 4 5 6]前序遍历顺序&#xff1a;[1 2 4 5 3 6]中序遍历顺序&#xff1a;[4 2 5 1 3 6]后序遍历顺序&#xff1a;[4 5 2 6 3 1] 层次遍历使用 BFS 实现&#xff0c;利用的就是 BFS…

写不了博客了吗?

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

像素的奇妙冒险:使用 Python 玩转彩色图片的灰度处理

文章目录 参考描述模块PillowPILPillow获取 Numpy获取 使用 Pillow 实现图片的灰度处理ImageOps.grayscale()convert() 原理灰度模式与彩色模式图片表示与三维数组ImageOps.grayscale() 与 convert(L) 背后的逻辑心理学灰度加权公式 Python 实现灰度模式下的灰度图片彩色模式下…

基于遥感的自然生态环境检测——实验三:生态因子提取

实验三&#xff1a;生态因子提取 一、实验目标 生态因子生成&#xff1b;生态因子归一化&#xff1b;生态环境评价 二、实验内容 根据经过大气校正后的影像生产土地覆盖指数、土壤指数以及坡度等&#xff0c;对土地覆盖指数、土壤指数以及坡度进行密度分割归一化&#xff1…

scikit-learn

一段时间只做一个事情。 比如不要想同时学习flink和scikit-learn。这实在是太难了。 pandas numpy pip install scikit-learn 使用的是venv环境 太难了。。 https://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html#sphx-glr-auto-examples-linear-mode…

建立人力资源运营团队的五个步骤

作为小企业主&#xff0c;设置人力资源运营可能不是您的首要任务。但是&#xff0c;随着您扩大运营规模和员工人数&#xff0c;您可能会遇到合规性和员工敬业度问题&#xff0c;从而阻碍您的业务增长。组建一个团队来照顾您的人力资源运营和员工可以让您专注于改进您的产品和满…

AI独立开发者:一周涨粉8万赚2W美元;推特#HustleGPT GPT-4创业挑战;即刻#AIHackathon创业者在行动 | ShowMeAI周刊

&#x1f440;日报&周刊合辑 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 这是ShowMeAI周刊的第7期。聚焦AI领域本周热点&#xff0c;及其在各圈层泛起的涟漪&#xff1b;拆解AI独立开发者的盈利案例&#xff0c;关注中美AIG…

Javaee Spring JdbcTemplate基本使用 基于xml配置方式

目录 哈哈哈哈&#xff0c;说好是要写一篇关于jdbcTemplate的基本使用&#xff0c;貌似说跑题了&#xff0c;但是主体还是用jdbctemplate实现的&#xff0c;有耐心看完的话相信能有点点收获的哦&#xff01; 项目结构&#xff1a; 小结&#xff1a; 遇到了个小问题&#xff0…

面试题——Arrays.asList()得到的List可以修改吗?

概述 前几天面试问的关于Arrays.asList()的问题&#xff0c;总结一下常见问题。 Arrays.asList()使用了什么设计模式 答案&#xff1a;使用了适配器模式。适配器模式简单来说就是不修改原对象&#xff0c;为了适应新的需求&#xff0c;适配成另一种接口或者类&#xff0c;我…

常见WebShell客户端的流量特征

以下的全是我在各个大佬哪里看文章做的总结-相当于我的笔记 中国蚁剑(AntSword) 大佬文章地址 https://www.cnblogs.com/NoCirc1e/p/16275608.htmlhttps://www.cnblogs.com/NoCirc1e/p/16275608.html 蚁剑PHP类WebShell链接流量 POST /uploadfiles/shell.php HTTP/1.1 Hos…

Windows安装Dolby Vision 杜比视界插件

前言 使用普通的播放器播放杜比视界视频时会出现发紫和发绿&#xff0c;两者来回切换的情况&#xff0c;要么使用专门的播放器&#xff0c;要么使用Windows自带播放器加上安装相应拓展 在使用Windows自带的“电影和电视”播放杜比视界(Dolby Vision)的视频时&#xff0c;需要安…

iOS 自定义Tab页

在iOS里面可以用UISegmentedControl控件来表示Tab页&#xff0c;但其样式难以修改&#xff0c;我们一般会自定义Tab页。 1. 自定义Tab页 在这里我们首先定义UKTabItemView用来显示其中的标签页。 // 标签页代理 protocol UKTabItemViewDelegate <NSObject>- (void)onT…

Kafka源码分析之Producer数据发送流程(四)

概述 书接上回的producer发送流程&#xff0c;在准备工作完成后&#xff0c;kafka的producer借助Sender和KafkaClient两大组件完成了数据的发送。其底层封装了java的NIO的组件channle以及selector&#xff0c;对于NIO组件不太熟悉的同学可以自行查询相关文档。 下面我整理了k…

从0搭建Vue3组件库(二):Monorepo项目搭建

本篇文章是从0搭建Vue3组件库系列文章第二篇,本篇文章将带领大家使用pnpm搭建一个简单的Monorepo项目,并完成包的关联与测试 什么是 Monorepo 其实很简单,就是一个代码库里包含很多的项目,而这些项目虽然是相关联的,但是在逻辑上是独立的,可以由不同人或者团队来维护 为什么…

Scala之集合(1)

目录 ​​​​​​​集合介绍&#xff1a; 不可变集合继承图&#xff1a;​编辑 可变集合继承图 数组&#xff1a; 不可变数组&#xff1a; 样例代码&#xff1a; 遍历集合的方法&#xff1a; 1.for循环 2.迭代器 3.转换成List列表&#xff1a; 4.使用foreach()函数&a…

WebServer项目(二)->linux网络编程基础知识

WebServer项目->linux网络编程基础知识其中&#xff0c;遇到的错误总结1). read&#xff1a;Connection reset by peer2).什么叫连接被重置&#xff1f;1. socket 介绍2. 字节序从主机字节序到网络字节序的转换函数&#xff1a;htons、htonl&#xff1b; 从网络字节序到主机…