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

提升 API 可靠性的五种方法

API 在我们的数字世界中发挥着关键的作用,使各种不同的应用能够相互通信。然而,这些 API 的可靠性是保证依赖它们的应用程序功能正常、性能稳定的关键因素。本文,我们将探讨提高 API 可靠性的五种主要策略。

1.全面测试

要确保 API 的可靠性,第一步是进行全面的测试。需要进行的测试包括:功能测试以验证 API 的正确运行,集成测试以确保 API 能与其他系统正常协同,以及负载测试以理解 API 在大规模使用下的表现。

自动化测试能在开发周期的早期发现问题,回归测试能保证新的修改不会对现有功能造成破坏。使用虚拟化或模拟技术可以模拟 API 依赖,进行更深度的测试。此外,为了确保 API 的提供者和消费者都能满足约定的接口,契约测试非常重要。

下面我们将使用 Go 的内置 testing 包,通过一个简单的例子对一个假设的 API 端点(用于访问 API 的 URI)进行测试。

假设我们有一个端点 GET /users/{id} ,用于返回用户的详细信息。

下面是我们可能编写的测试代码:

package mainimport (
"net/http"
"net/http/httptest"
"testing"
)// 这是一个简化的实际处理器函数示例
func UserHandler(w http.ResponseWriter, r *http.Request) {
// ... 处理器逻辑
}func TestUserHandler(t *testing.T) {
req, err := http.NewRequest("GET", "/users/1", nil)
if err != nil {
t.Fatal(err)
}rr := httptest.NewRecorder()
handler := http.HandlerFunc(UserHandler)handler.ServeHTTP(rr, req)if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}// 你还可以检查响应体是否符合预期的输出
expected := `{"id": "1", "name": "John Doe"}`
if rr.Body.String() != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}
}

这个测试创建了一个新的 HTTP 请求,模拟了对我们的  /users/{id} 端点的调用,然后把请求传递给了处理器函数。测试会检查响应状态是否为  200 OK(即我们期望的成功请求应返回的结果)以及响应体是否与预期的输出一致。

这个例子只是一个简单的示例,在实际应用中,你可能会面临更复杂的场景,包括测试各种边界条件、错误路径等。此外,net/http/httptest 包提供了许多用于测试 HTTP 客户端和服务器的工具。

总之,你可以结合单元测试、性能测试和持续的集成测试,为你的 API 构建一个全面的测试套件。

单元测试的目的是确保你的 API 中每个组件的正确性。它通过验证每个部分的功能和隔离它们,使得你可以在早期发现并纠正问题。单元测试通常通过模拟依赖项并独立测试函数来完成。在 Go 语言中,可以利用诸如 testify 等包来达成这一目标。

性能测试则是为了在高流量的情况下对 API 进行压力测试。这种测试有助于你确定系统在高负载情况下的表现,识别瓶颈,并确保 API 能处理真实世界的使用情况。性能测试可以使用 JMeter 或Gatling 等工具进行。

最后,持续集成测试则通过模拟用户或客户端对 API 进行一系列连续操作,来测试系统的工作流程。这类测试能够提供对端到端工作流程、潜在的障碍或延迟,以及整体用户体验的深入理解。这个过程可以自动化并集成到你的 CI/CD 流程中,使得你可以持续监控并及时反馈任何代码更改的影响。

通过实施包括功能测试、单元测试、性能测试和持续合成测试在内的全面的测试策略,你可以确保你的 API 不仅稳定且高性能,还能为使用者提供无缝的体验。而在问题出现时,这种多元化的测试方法可以帮助你快速定位并解决问题的根源。

2.版本控制

在维护软件系统的稳定性方面,API 版本管理扮演了核心角色。随着时间推移,API 可能会随着需求变化和优化,如果没有适当的版本管理,可能会对现有的客户端应用造成破坏。这就是 API 版本管理的关键所在。通过维护 API 的各个版本,你可以在引入新功能和优化的同时,确保不影响使用旧版本 API 的应用。

这种策略提升了系统的稳定性,因为即使 API 经过改动和优化,客户端应用依然可以稳定运行。它让开发者能够部署 API 更新,而不需要担心这些变化会对正在运行的应用造成破坏,保障了系统的稳定性和正常运行。

保持向后兼容性是实现 API 稳定性的关键一环,也就是说,新系统应能与旧版 API 兼容。即使新的版本发布,使用旧 API 版本的应用依然可以正常运行。这避免破坏用户体验,并给了开发者足够的时间,让他们可以按照自己的节奏更新应用以适应新的 API ,而不是为了防止应用出错而被迫升级。这样做,有助于创建一个整体上更稳定、更强大和更具有弹性的系统。

示例

在 Go 语言中,我们可以使用多种方式来进行 API 的版本管理。

下面这个例子展示了如何通过在 URL 中嵌入 API 版本实现版本管理,这种方法通常被称为"路径版本控制"。

package mainimport (
"fmt"
"net/http"
)func handleRequest(w http.ResponseWriter, r *http.Request) {switch r.URL.Path {
case "/v1/users":
fmt.Fprintf(w, "You've hit the version 1 of the users API!")
case "/v2/users":
fmt.Fprintf(w, "You've hit the version 2 of the users API!")
default:
http.NotFound(w, r)
}
}func main() {
http.HandleFunc("/", handleRequest)
http.ListenAndServe(":8080", nil)
}

在这个例子中,我们定义了一个处理函数,它根据请求的 URL 路径来匹配响应的代码。当访问 "/v1/users" 路径时,我们认为这是对我们 API 第一版本的请求。同样地,"/v2/users" 则对应我们 API 的第二个版本。通过添加更多的分支,你可以轻松地扩展这种模式以适应更多版本和端点。

此外,你也可以通过自定义头部或媒体类型版本管理(也称为"内容协商")来实现版本管理。

不论你选择何种版本管理策略,都应为 API 的每个版本维护清晰且最新的文档,这是一种良好的实践。

但是,我们也需要谨慎使用版本管理。我们应尽可能地保持向后兼容性,并提供清晰的文档。文档应详细说明每个新版本中的变化,并提供废弃旧版本的合理时间表。

3. 面向失败设计

在理想情况下,API 始终能够正确运行。然而在实际操作中,出现失败的情况并不罕见。在设计 API 的过程中,我们需要考虑其容错能力,这可能涉及到诸如优雅降级(即系统继续运行但是功能有所缩减)和故障转移机制(即出现故障时,系统自动切换到备份系统)等策略。

将明确的错误消息和代码纳入 API,能有助于应用程序更好地理解问题所在以及采取应对策略。我们可以通过重试逻辑、速率限制和断路器,让系统从临时性问题中恢复,避免故障级联。

下图显示了应对各种故障类型的操作方法:

示例:断路器模式

在断路器模式中,Go 语言有一个叫 go-hystrix 的热门库,该库专注于延迟和容错处理。它主要是在服务停止时,通过快速失败阻止故障级联。以下是一个基本示例:

package mainimport (
"github.com/afex/hystrix-go/hystrix"
"log"
"net/http"
"errors"
)func main() {
hystrix.ConfigureCommand("my_command", hystrix.CommandConfig{
Timeout:               1000,
MaxConcurrentRequests: 100,
ErrorPercentThreshold: 25,
})http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
err := hystrix.Do("my_command", func() error {
// 调用其他服务
return nil
}, nil)if err != nil {
log.Printf("Failed to talk to other services: %v", err)
http.Error(w, "Failed to talk to other services", http.StatusInternalServerError)
}
})log.Fatal(http.ListenAndServe(":1234", nil))
}

在上述示例中,我们将一个命令封装在 hystrix.Do() 中。如果基于我们设置的参数,传入 Do() 的函数失败或超时,断路器就会被触发,后续的调用将会立即失败,而不再调用该函数。

请注意,这只是一个基本的示例,实际应用场景将涉及更多复杂的用法,需要针对这个库以及其他的弹性实用程序库涉及的各种参数进行细致调整。请务必阅读各种库的文档,深入理解如何在你的代码中有效地使用它们。

4. 监控与分析

实时监控与及时分析对于保证 API 的稳定性至关重要。执行一套全面的 API 监控策略可以包括对运行时间、性能以及错误的检测,这有助于我们在问题扩散影响用户前,及时发现并处理。

同时,深入分析 API 的使用模式可以让我们得到重要的洞察。了解到高峰负载时段、最常使用的端点以及其他使用详情后,您就可以主动地找出可能存在的弱点,并据此进行 API 优化。

选择正确的指标去追踪,对于了解你的 API 的健康状态和性能至关重要。以下是一些需要考虑的关键指标:

1.吞吐量:您的 API 单位时间内处理的请求数量,可以进一步分为端点、HTTP 方法(如 GET、POST、PUT、DELETE 等)或响应状态码。

2.错误率:单位时间内的错误响应数量,通常是指含有 4xx 或 5xx 状态码的响应。同吞吐量一样,这个指标也可以按端点、HTTP 方法或具体的状态码进行细分。

3.延迟:处理一个请求所需的时间,通常以一系列百分位数(如第 50、95 和 99 百分位)来追踪,这可以帮助您了解典型和极端情况下的性能表现。您可能需要针对不同的端点或 HTTP 方法单独追踪此项。

4.流量:发送和接收的数据量,可以按端点、HTTP 方法或响应状态码进行细分。

5.可用性:您的 API 正常运行并能够处理请求的时间占比,可以作为一个整体进行测量,或者针对每一个单独的端点进行测量。

6.饱和度:系统达到最大容量的程度,这可以通过测量 CPU 使用率、内存使用率、磁盘 I/O 或其他可能限制系统处理更多负载的资源来了解。

7.断路器触发:如果您使用断路器模式处理故障,您可能需要追踪断路器被触发的频率,这可以帮助您了解 API 或其依赖项失败的频率。

请记住,根据你的 API 特性和应用需求,选择追踪的具体指标可能会有所不同。关键是要选择那些能为你提供有意义的 API 健康状况和性能洞察力的指标。

以 Prometheus 为例:

Prometheus 是一款内建客户端库的开源系统监控和警告工具包,它支持用各种语言度量您的服务。下面就是一个示例,说明如何使用 Go 客户端库在 HTTP 端点上展示指标。

我们将使用 Prometheus 的 Go 客户端 来展示和创建这些指标。

package mainimport (
"net/http""github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)var (
httpRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Number of HTTP requests",
},
[]string{"path"},
)httpRequestDuration = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "http_request_duration_seconds",
Help: "Duration of HTTP requests in seconds",
},
[]string{"path"},
)
)func init() {
// Register the metrics.
prometheus.MustRegister(httpRequestsTotal)
prometheus.MustRegister(httpRequestDuration)
}func handler(w http.ResponseWriter, r *http.Request) {
// Increment the counter for the received requests.
httpRequestsTotal.WithLabelValues(r.URL.Path).Inc()// Measure the time it took to serve the request.
timer := prometheus.NewTimer(httpRequestDuration.WithLabelValues(r.URL.Path))
defer timer.ObserveDuration()// Handle the request.
w.Write([]byte("Hello, world!"))
}func main() {http.HandleFunc("/", handler)// Expose the registered metrics via HTTP.
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}

在这个例子中,我们创建并注册了两个指标:http_requests_total 和 http_request_duration_seconds。前者是一个计数器,每接收到一个请求就增加一次计数,后者是一个汇总指标,用于记录处理每个请求所花费的时间。

然后,我们创建了一个 HTTP 处理器,每处理一个请求,就会增加计数器并测量请求的执行时长。我们利用 promhttp.Handler() 在 /metrics 端点上展示这些指标。

现在,只要你启动了服务器并向其发送请求,就可以通过访问 http://localhost:8080/metrics 或者使用工具如 curl 来查看这些指标。

这只是一个基础的示例,在实际应用中,你可能会希望追踪更多的指标,并基于其他维度(如 HTTP 方法、响应状态码等)对它们进行细分。

5. 利用 API 网关

API 网关是一种强大的工具,能有效提升 API 的健壮性。作为系统的统一入口,API 网关能够处理诸如路由、负载均衡、认证、限流等多项功能。通过将这些问题从 API 本体中抽离,你能更专注于业务逻辑,而非基础设施。

另外,API 网关还可提供额外的弹性特性,如自动故障转移、为提高性能而对响应进行缓存,以及在高负载时对请求进行缓冲或排队。

下面列出了 API 网关能提供的部分功能,帮助你为技术栈选择适合的 API 网关:

  1. 请求路由: API 网关可以依据请求中的路由信息将客户端请求路由到合适的后端服务。
  2. API 版本管理: API 网关能管理多版本的 API,允许客户端并行使用不同版本。
  3. 限流: 为了避免请求过量淹没后端服务,API 网关能够限制某个或某组客户端的请求速率。
  4. 身份验证和授权: API 网关通常处理客户端请求的身份验证和授权,确保只有经过验证并授权的请求才能到达后端服务。
  5. API 密钥管理: API 网关通常管理 API 密钥,这些密钥用于跟踪和控制 API 的使用方式。
  6. 缓存: 为了提升性能并降低后端服务的负载,API 网关可以缓存后端服务的响应,并在收到相同的请求时返回缓存的响应。
  7. 请求和响应转换: API 网关可以将请求和响应转换为客户端或后端服务所需的格式。
  8. 熔断器功能: 当服务出现故障,API 网关可以通过将请求路由到正常运行的服务来防止应用程序崩溃。
  9. 监控和分析: API 网关能收集 API 的使用和性能数据,用于分析、监控和警报。
  10. 安全策略: API 网关可以执行安全策略,如 IP 白名单,同时防止 SQL 注入、跨站脚本攻击(XSS)等安全威胁。

以下是一些知名的开源 API 网关:

  1. Kong:Kong 是一个云原生、快速、可扩展、分布式的微服务管理层(也称为 API 网关或 API 中间件)。自 2015 年以来,它以开源项目的形式存在,其核心功能是用 Lua 编写的,并运行在 Nginx 网络服务器上。
  2. Tyk:Tyk 是一个开源的 API 网关,运行速度快且可扩展性强,既可以运行在独立服务器上,也可与已有的 Nginx 安装进行协同工作。
  3. Express Gateway:Express Gateway 是一个基于 Express.js 构建的微服务 API 网关。该网关完全可扩展,不依赖任何特定框架,能够在短时间内提供强大且可扩展的解决方案。
  4. KrakenD:KrakenD 是一个高性能的开源 API 网关。KrakenD 消除了所有 SOA 架构的复杂性,以支持应用程序开发者快速发布新功能,同时保持出色的性能。

总的来说,提升 API 的可靠性不是一项一次性任务,而是需要持续投入的工作。这包括严格的测试、精确的版本控制、遵循好的设计原则,智能地使用如 API 网关这样的工具,以及持续的监控和分析。有了这些策略,你就能构建出能经受住时间考验并为你的应用程序提供可靠基础的 API。

相关文章:

提升 API 可靠性的五种方法

API 在我们的数字世界中发挥着关键的作用,使各种不同的应用能够相互通信。然而,这些 API 的可靠性是保证依赖它们的应用程序功能正常、性能稳定的关键因素。本文,我们将探讨提高 API 可靠性的五种主要策略。 1.全面测试 要确保 API 的可靠性…...

【K8S 系列】认识k8s、k8s架构

一、什么是k8s? Kubernetes 简称 k8s,是支持云原生部署的一个平台,k8s 本质上就是用来简化微服务的开发和部署的,用于自动化部署、扩展和管理容器化应用的开源容器编排技术。对于传统的docker其实也提供了容器编排的技术docker-compose&…...

通过这5步,快速成为数据分析师

1. 学习基础知识:掌握统计学、数学和编程等基础知识是成为数据分析师的第一步。你可以参加在线课程、教育平台或自学来提高自己的技能。 2. 学习数据分析工具:熟练使用数据分析工具如Python、R和SQL等是必要的。这些工具可以帮助你处理和分析大量的数据…...

深入解析 Spring 和 Spring Boot 的区别

目录 引言 1. 设计理念 1.1 Spring 框架的设计理念 1.2 Spring Boot 的设计理念 2. 项目配置 2.1 Spring 框架的项目配置 2.2 Spring Boot 的项目配置 3. 自动配置 3.1 Spring 框架的自动配置 3.2 Spring Boot 的自动配置 4. 微服务支持 4.1 Spring 框架的微服务支持…...

Python日期范围按旬和整月以及剩余区间拆分

昨天见到了一个比较烧脑的问题: 咋一看可能理解问题比较费劲,可以直接看结果示例: 当然这个结果在原问题上基础上有一定改进,例如将同一天以单个日期的形式展示。 如何解决这个问题呢?大家可以先拿测试用例自己试一下…...

windows安装sqlserver2008后连接失败问题

刚安装好的sqlserver在安装服务器上,直接使用Windows身份认证登录就报错 未找到或无法访问服务器。请验证实例名称是否正确并且SQL Server已配置为允许远程连接。(provider:命名管道提供程序,error:40 -无法打开到SQLS…...

mysql innodb知识记录

官方文档 官网架构图 innodb 特性 内存 buffer pool 采用优化后的LRU算法, 3/8 of the buffer pool is devoted to the old sublist.The midpoint of the list is the boundary where the tail of the new sublist meets the head of the old sublist.When In…...

在排序数组中查找元素的第一个和最后一个位置(Java详解)

一、题目描述 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 示…...

k8s 安装firewalld导致的网络疑难问题处理

场景 ubuntu 操作系统,部署了k8s集群,n 台 机器,某些机器之间 telnet ip 10250不通。 ufw 是关闭的,然后抓包会看到如下错误 04:43:09.154362 IP 192.168.1.3.56608 > 192.168.1.183.8000: Flags [S], seq 3664350430, win 64240, options [mss 1460,sackOK,TS val 281…...

人工智能中的巨兽:图神经网络大模型的崛起

导言 图神经网络大模型的涌现标志着人工智能领域的一次革命。本文将深入研究这些庞大而强大的模型,探讨其背后的技术原理、关键应用以及引发的社会影响。 1. 技术原理 图神经网络大模型以其对图结构数据的卓越处理能力而著称。其技术原理包括: 图卷积神…...

【LeetCode刷题笔记(6-2)】【Python】【三数之和】【双指针】【中等】

文章目录 引言三数之和题目描述示例示例1示例2示例3 提示 解决方案3:【双指针】结束语 三数之和 引言 编写通过所有测试案例的代码并不简单,通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程…...

02_Web开发基础之JavaScript

Web开发基础之JavaScript 学习目标和内容 1、能够描述Javascript的作用 2、能够使用分支结构if语句逻辑判断 3、能够使用其中一种循环语句 4、能够定义javaScript中的函数 5、能够定义javaScript中的对象 6、能够描述DOM的作用 7、能够通过DOM操作HTML标签元素及其属性 8、能够…...

如何控制Elasticsearch搜索的相关性?

控制相关性 纯粹处理结构化数据(例如日期、数字和 字符串枚举)很简单:他们只需要检查一个文档(或 行,在关系数据库中)与查询匹配。 虽然布尔值是/否匹配是全文搜索的重要组成部分,但它们 光靠自己是不够的。相反,我们还需要知道每个的相关性 document 是查询。全文搜索…...

基于urllib库的网页数据爬取

实验名称: 基于urllib库的网页数据爬取 实验目的及要求: 【实验目的】 通过本实验了解和掌握urllib库。 【实验要求】 1. 使用urllib库爬取百度搜索页面。 2. 使用urllib库获取百度搜索的关键字搜索结果(关键字任选)。 实验原理及…...

Python如何匹配库的版本

目录 1. 匹配库的版本 2. Python中pip,库,编译环境的问题回答总结 2.1 虚拟环境 2.2 pip,安装库,版本 1. 匹配库的版本 (别的库的版本冲突同理) 在搭建pyansys环境的时候,安装grpcio-tools…...

日志审计在网络安全中的重要性

日志审计是一种通过分析、识别和验证各种日志信息,以帮助企业了解其网络和系统的安全状态和活动的过程。这些日志信息可能来自各种来源,包括服务器、网络设备、应用程序、操作系统等。 日志审计的主要功能包括: 1.识别潜在的安全威胁&#…...

浅谈基于不信任的防御性编程

背景 在实际开发过程中,我们经常遇到这样的场景: 后端报错了,手忙脚乱一顿排查,发现是前端传的参数为空,或者格式不对;后端又报错了,传参没问题,根据日志流发现,是某“给…...

线性代数(一)

1.标量:标量由只有⼀个元素的张量表⽰。 x np.array(3.0) y np.array(2.0) x y, x * y, x / y, x ** y (array(5.), array(6.), array(1.5), array(9.))2.向量:向量可以被视为标量值组成的列表,列向量是向量的默认⽅向。 x np.arange(4…...

k8s-learning-why we need pod

应用场景 应用从虚拟机迁移到容器中 为什么虚拟机中的应用不能无缝迁移到容器中 虚拟机中应用:一组进程,被管理在systemd或者supervisord中 容器的本质:一个容器一个进程 所以将运行在虚拟机中的应用无缝迁移到容器中,与容器…...

【CASS精品教程】cass11提示“请不要在虚拟机中运行此程序”的解决办法

文章目录 一、问题提示二、解决办法一、问题提示 按照正常安装教程安装好南方测绘cass 11之后,打开的时候可能会有以下提示:请不要在虚拟机中运行此程序,如下图所示: 遇到问题,咱们就想办法解决问题,下面将自己尝试的方法及最终解决情况跟大家说一下,供参考。 二、解决…...

【算法Hot100系列】正则表达式匹配

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

html 基础学习笔记

Date:20231212 html标签 基础学习笔记 一、web和internet 1.1、Internet简介 Internet 是一个全球性的计算机互联网络,中文名称有"因特网"、“国际互联网”、“网际网”、"交互网络"等Internet提供的主要服务 Telnet、Email、www、BBS、FTP等…...

7-4 天梯赛的善良

天梯赛是个善良的比赛。善良的命题组希望将题目难度控制在一个范围内,使得每个参赛的学生都有能做出来的题目,并且最厉害的学生也要非常努力才有可能得到高分。 于是命题组首先将编程能力划分成了 106 个等级(太疯狂了,这是假的&…...

案例精选|聚铭综合日志分析系统助力长房集团“智慧房产”信息化建设

长沙房产(集团)有限公司(简称“长房集团”)始创于2004年3月,是一家由长沙市人民政府授权组建的国有独资企业。截至2021年底,企业总资产逾452亿元,总开发面积1300多万平方米,已开发项…...

HarmonyOS给应用添加消息通知

给您的应用添加通知 通知介绍 通知旨在让用户以合适的方式及时获得有用的新消息,帮助用户高效地处理任务。应用可以通过通知接口发送通知消息,用户可以通过通知栏查看通知内容,也可以点击通知来打开应用,通知主要有以下使用场景…...

【C语言】cache和程序访问的局部性对程序性能的影响

文章目录 1.源程序比较其性能影响2.内存分配(1)静态存储区(static):(2)栈区(stack):(3)堆区(heap&…...

数字棱形(课程F)

输入1个整数N,输出N行的如下形状的数字棱形。 例如:N4时: ___1 __222 _33333 4444444 _33333 __222 ___1 (注:上面使用下划线’_’表示空格,以避免看不清造成误解) 输入格式 第一行1个正整数:N&#xff0…...

如何查看PHP信息

创建一个 PHP 文件&#xff0c;比如 info.php&#xff0c;在其中添加以下代码&#xff1a; <?php phpinfo(); ?>访问这个文件&#xff08;例如&#xff0c;在浏览器中输入 http://localhost/info.php&#xff09;&#xff0c;它会显示 PHP 的所有配置信息。在这个页面…...

Vue3+ts实现页面跳转及参数传递

## 列表页 <script lang"ts" setup> import { reactive, toRefs } from vue // 1 引入useRouter路由信息方法 import { useRouter } from vue-router // 2 获取实例 const router useRouter()const gotoDetail (index: string) > {router.push({path: …...

日志框架Log4j、JUL、JCL、Slf4j、Logback、Log4j2

1. JAVA日志框架 1.1 为什么程序需要记录日志 我们不可能实时的24小时对系统进行人工监控&#xff0c;那么如果程序出现异常错误时要如何排查呢&#xff1f;并且系统在运行时做了哪些事情我们又从何得知呢&#xff1f;这个时候日志这个概念就出现了&#xff0c;日志的出现对系…...

怎样在领英上做公司网站/免费外链网

HTML介绍 HTML&#xff08;HyperText MarkupLanguage&#xff09;简称超文本标记语言。它和CSS、JavaScript组合完成一个网页的设计。对于一个网页&#xff0c;HTML定义网页的结构&#xff0c;CSS描述网页的样子&#xff0c;JavaScript则实现人机交互。 HTML语义化 说起HTML&am…...

专业做网站的公司有没有服务器/运营培训班学费大概多少

转载于:https://blog.51cto.com/xcf007/109359...

石景山网站制作案例/建设网站的步骤

在本博客中已经详细介绍了基于ADS1298的心电图仪&#xff0c;这里不再赘述其技术细节&#xff0c;因为都是大同小异的。 与心电信号不同&#xff0c;肌电信号的频率高、幅度高&#xff0c;但是肌电不需要威尔逊终端和右腿驱动。 8通道的肌电图仪的整体方案如下图所示。 其实物…...

塘沽网站建设优化/电商运营转行后悔了

生活的许多因素可能会引起皮肤老化&#xff0c;皮肤松弛&#xff0c;让皮肤状态看起来更老。为了让皮肤变得更好&#xff0c;我们必须注意饮食&#xff0c;调整心情&#xff0c;不仅如此还需要使用美容仪对自己的皮肤进行保养&#xff0c;让我们一起来了解一下如何避免皮肤松弛…...

jquery 苹果网站/seo关键词推广价格

CentOS7下修改主机名第一种&#xff1a;hostname 主机名01.hostname 主机名称 这种方式&#xff0c;只能修改临时的主机名&#xff0c;当重启机器后&#xff0c;主机名称又变回来了。第二种&#xff1a;hostnamectl set-hostname <hostname>命令行中输入01.hostnamectl s…...

acg大神做的网站/百度网盘登录入口官网

Liberty means responsibility. That is why most men dread it. —  George Bernard Shaw Unless a man has talents to make something of himself, freedom is an irksome burden. —  Eric Hoffer 起这么吓人的一个题目&#xff0c;其实只是想写一下 Linux。但我保证决不…...