字节赫兹 框架教程 二 Routers

【字节青训营-8】:初探字节微服务框架 Hertz 基础使用及进阶(上) 本文主要记录字节微服务框架Hertz的一些基础使用,如客户端、路由、Engine、网络库等 阅读详情

路由

路由注册

Hertz 提供了 GET、POST、PUT、DELETE、ANY 等方法用于注册路由。

方法介绍
Hertz.GET用于注册 HTTP Method 为 GET 的方法
Hertz.POST用于注册 HTTP Method 为 POST 的方法
Hertz.DELETE用于注册 HTTP Method 为 DELETE 的方法
Hertz.PUT用于注册 HTTP Method 为 PUT 的方法
Hertz.PATCH用于注册 HTTP Method 为 PATCH 的方法
Hertz.HEAD用于注册 HTTP Method 为 HEAD 的方法
Hertz.OPTIONS用于注册 HTTP Method 为 OPTIONS 的方法
Hertz.Handle这个方法支持用户手动传入 HTTP Method 用来注册方法,当用于注册普通的 HTTP Method 方法时和上述的方法作用是一致的,并且这个方法同时也支持用于注册自定义 HTTP Method 方法
Hertz.Any用于注册所有 HTTP Method 方法
Hertz.StaticFile/Static/StaticFS用于注册静态文件

实例代码:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main(){
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"))

	h.StaticFS("/", &app.FS{Root: "./", GenerateIndexPages: true})

	h.GET("/get", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "get")
	})
	h.POST("/post", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "post")
	})
	h.PUT("/put", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "put")
	})
	h.DELETE("/delete", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "delete")
	})
	h.PATCH("/patch", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "patch")
	})
	h.HEAD("/head", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "head")
	})
	h.OPTIONS("/options", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "options")
	})
	h.Any("/ping_any", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "any")
	})
	h.Handle("LOAD","/load", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "load")
	})
	h.Spin()
}

路由组

Hertz 提供了路由组 ( Group ) 的能力,用于支持路由分组的功能,同时中间件也可以注册到路由组上。

示例代码:


package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main(){
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
	v1 := h.Group("/v1")
	v1.GET("/get", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "get")
	})
	v1.POST("/post", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "post")
	})
	v2 := h.Group("/v2")
	v2.PUT("/put", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "put")
	})
	v2.DELETE("/delete", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "delete")
	})
	h.Spin()
}

在路由组中使用中间件

如下示例在路由组中使用 BasicAuth 中间件。

示例代码 1:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/middlewares/server/basic_auth"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main() {
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
	// use middleware
	v1 := h.Group("/v1", basic_auth.BasicAuth(map[string]string{"test": "test"}))

	v1.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		ctx.String(consts.StatusOK,"ping")
	})
	h.Spin()
}

示例代码 2:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/middlewares/server/basic_auth"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main() {
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
	v1 := h.Group("/v1")
	// use `Use` method
	v1.Use(basic_auth.BasicAuth(map[string]string{"test": "test"}))
	v1.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		ctx.String(consts.StatusOK,"ping")
	})
	h.Spin()
}

路由类型

Hertz 支持丰富的路由类型用于实现复杂的功能,包括静态路由、参数路由 (命名参数、通配参数)。

路由的优先级:静态路由 > 命名参数路由 > 通配参数路由

命名参数路由

Hertz 支持使用 :name 这样的命名参数设置路由,并且命名参数只匹配单个路径段。

如果我们设置/user/:name路由,匹配情况如下

路径是否匹配
user/gordon匹配
/user/you匹配
/user/gordon/profile不匹配
/user/不匹配

通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。

示例代码:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main(){
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
	// This handler will match: "/hertz/version", but will not match : "/hertz/" or "/hertz"
	h.GET("/hertz/:version", func(ctx context.Context, c *app.RequestContext) {
		version := c.Param("version")
		c.String(consts.StatusOK, "Hello %s", version)
	})
	h.Spin()
}

通配参数路由

Hertz 支持使用 *path 这样的通配参数设置路由,并且通配参数会匹配所有内容。

如果我们设置/src/*path路由,匹配情况如下

路径是否匹配
/src/匹配
/src/somefile.go匹配
/src/subdir/somefile.go匹配

通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。

示例代码:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main(){
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
	// However, this one will match "/hertz/v1/" and "/hertz/v2/send"
	h.GET("/hertz/:version/*action", func(ctx context.Context, c *app.RequestContext) {
		version := c.Param("version")
		action := c.Param("action")
		message := version + " is " + action
		c.String(consts.StatusOK, message)
	})
	h.Spin()
}

在浏览器访问http://localhost:8080/hertz/my/study的结果
在这里插入图片描述

使用匿名函数与装饰器注册路由

在使用匿名函数或装饰器注册路由时,如果我们使用 RequestContext.HandlerName() 获取 handler 名称则会获取到错误的名称。

这里需要使用 Hertz 提供的 GETEX、POSTEX、PUTEX、DELETEEX、HEADEX、AnyEX、HandleEX 方法并手动传入 handler 名称注册路由,使用 app.GetHandlerName 获取 handler 名称。

示例代码:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main() {
	h := server.Default()
	h.AnyEX("/ping", func(c context.Context, ctx *app.RequestContext) {
		ctx.String(consts.StatusOK, app.GetHandlerName(ctx.Handler()))
	}, "ping_handler")
	h.Spin()
}

获取路由注册信息

Hertz 提供了 Routes 获取注册的路由信息供用户使用。

路由信息结构:

// RouteInfo represents a request route's specification which contains method and path and its handler.
type RouteInfo struct {
    Method      string   // http method
    Path        string   // url path
    Handler     string   // handler name
    HandlerFunc app.HandlerFunc
}

// RoutesInfo defines a RouteInfo array.
type RoutesInfo []RouteInfo
示例代码:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main() {
	h := server.Default()
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"})
	})
	routeInfo := h.Routes()
	hlog.Info(routeInfo)
	h.Spin()
}

NoRoute 与 NoMethod 使用

Hertz 提供了 NoRoute 与 NoMethod 方法用于全局处理 HTTP 404 与 405 请求。 当使用 NoMethod 时需要与 WithHandleMethodNotAllowed 配合使用。

示例代码:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main() {
	h := server.Default(server.WithHandleMethodNotAllowed(true))
	h.POST("/ping", func(c context.Context, ctx *app.RequestContext) {
		ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"})
	})
	// set NoRoute handler
	h.NoRoute(func(c context.Context, ctx *app.RequestContext) {
		ctx.String(consts.StatusOK, "no route")
	})
	// set NoMethod handler
	h.NoMethod(func(c context.Context, ctx *app.RequestContext) {
		ctx.String(consts.StatusOK, "no method")
	})

	h.Spin()
}

在这里插入图片描述

重定向尾斜杠

Hertz 在默认情况下会根据请求 path 末尾的 / 自动进行转发。如果 router 中只有 /foo/,那么请求 /foo 会被自动重定向到 /foo/;如果 router 中只有 /foo,那么 /foo/ 会被重定向到 /foo。

这样的请求除 GET 以外的请求方法都会触发 307 Temporary Redirect 状态码,而 GET 请求会触发 301 Moved Permanently 状态码。

可以在配置中取消,如下:

package main

import "github.com/cloudwego/hertz/pkg/app/server"

func main() {
    h := server.New(server.WithRedirectTrailingSlash(false))
	...
}
Go 语言数据库事务详解:从 db.Begin 到 Tx 的正确用法 本文详解Go语言中database/sql事务的正确用法,从*sql.Tx的底层模型出发,阐述事务与连接池的关系,提供标准事务模板,并强调使用db.BeginTx控制隔离级别与超时。重点剖析常见陷阱:误用db而非tx执行SQL、defer顺序错误、忽略Commit错误、事务过长导致资源耗尽等。结合可运行示例,涵盖事务内查询、预处理语句及保存点模拟嵌套事务,全面覆盖工程实践中的关键细节。 阅读详情

相关推荐

从零开始学习 Go 1.25 编程

今天是你新生活的第一天,无论年龄、背景如何,改变从这一刻开始。CodeGym帮助成千上万普通人转型为程序员,从零基础到掌握Go语言,完成真实项目,甚至入职心仪岗位。Go语言简洁高效,适合服务器端开发,是云基础设施、微服务和高负载系统的首选。2026年正是入行良机,你的经验反而是优势。别犹豫,迈出第一步,你将收获技能、自信与全新人生。🚀

sinat_25548781的博客 91

golang入门笔记——Hertz

Hertz是字节跳动研发的企业级微服务HTTP框架,具有高易用性、易扩展、低时延等特点。是基于自研网络库Netpoll开发的内部框架Hertz。Hertz框架整体上满足:1.极致性能优化的问题性2.面对未来不可控需求的扩展能力,Hertz采用了4层分层设计(应用层、路由层、协议层、传输层),保证各个层级功能内聚,同时通过层级之间的接口达到灵活扩展的目标。

qq_43716830的博客 5175

自研半导体Fab缺陷分析系统:从Klarf解析到Defect Map可视化的实战替代方案

本文分享了自研半导体Fab缺陷分析系统的实战经验,重点解析了Klarf文件格式与坐标系转换的核心技术,并详细介绍了从数据解析到Defect Map可视化的完整实现路径。该系统旨在为成本敏感或追求技术自主的团队提供一套功能完备的Klarity Defect平替方案,有效降低对昂贵商业软件的依赖,实现缺陷数据的自主分析与可视化。

y7z8a的博客 710

Restful get请求,前后端搭配优雅实现可选路径参数

Get 请求带路径参数和不带路径参数,往往需要写两个方法处理,怎么才能优雅呢?

i5858588的博客 459

opencv图像去畸变

opencv图像去畸变

智能机器人产学研基地 4872

为什么你的单细胞数据总有问题?可能是忽略了scDblFinder这个神器

本文深入剖析了单细胞数据分析中异质性双细胞这一常见但易被忽视的痛点,并重点介绍了scDblFinder这一神器。scDblFinder通过机器学习模型,能精准识别并过滤同一样本内的异质性双细胞,有效解决其导致的聚类模糊、信号混淆等问题,从而显著提升数据洁净度与下游分析结果的可靠性。

brandy的博客 453

字节开源WEB框架Hertz太香啦!

Hertz[həːts] 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架、、的优势, 并结合内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。

xhbzl的博客 6518

LPDDR5时序精调:深入解析Read Gate Training的两种模式

本文深入解析了LPDDR5内存中关键的Read Gate Training技术,详细对比了RDQS Toggle Mode(翻转模式)与Enhanced RDQS Mode(增强模式)的工作原理、时序参数及适用场景。文章阐述了在高速数据传输下精准校准时序的必要性,并提供了两种模式的实战选型指南与系统级调试思路,帮助工程师优化内存性能与稳定性。

weixin_29219189的博客 368

HTTP 框架 Hertz 入门

从本篇笔记开始将介绍 Go 框架三件套(Web / RPC / ORM),框架的学习有助于后续课程的学习以及大项目的完成。本文主要介绍字节跳动的开源 Golang 微服务 HTTP 框架 Hertz。Hertz 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架fasthttpginecho的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。

weixin_57209831的博客 2177

FPGA新手必看:Create HDL Wrapper和Generating Output Products到底该先用哪个?

本文深入解析了FPGA设计中Create HDL Wrapper与Generating Output Products的正确使用顺序,帮助新手避免常见错误。详细介绍了两者的功能差异、执行顺序的底层逻辑以及工程管理的最佳实践,特别适合使用Vivado进行FPGA开发的初学者。

xk7n92h3p5m的博客 1065

C#:实现统计图像主颜色的算法(附完整源码)

C#:实现统计图像主颜色的算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 520

一分钟使用高性能框架 Hertz

点击上方蓝色字体,选择“设为星标”回复”云原生“获取基础架构实践Hertz 是什么Hertz[həːts] 是字节 CloudWeGo 团队一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttp、gin、echo 的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。如今越来越多的微服务选择使用 Golang...

wangsofa的博客 2060

Fiori Elements Analytical List Page 标题区配置全攻略:从变体、过滤模式到 UI.KPI 的工程化落地

ALP标题区是Fiori Elements Analytical List Page的核心交互区域,承担变体管理、过滤模式切换、KPI展示等关键功能。本文系统解析了标题区的组成结构、可用能力及工程实现要点,包括:1)标题区包含过滤类型切换、全局KPI、变体管理等交互元素;2)详细说明视觉过滤与紧凑过滤的同步规则及实现方式;3)介绍OData V2下通过UI.KPI注解配置标题区KPI的方法;4)提供manifest.json配置示例和CDS注解写法。文章还对比了V2与V4版本的差异,为ALP开发提供实用指导

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 245

Go语言学习指南——HTTP框架Hertz

Hertz是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttp、gin、echo的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。

m0_62275194的博客 1940

RTX6000 PRO BLACKWELL 最优 CUDA 版本选择指南(适配 vLLM/SGLang 大模型推理)

本文针对NVIDIA Blackwell架构RTX6000PRO显卡部署vLLM/SGLang大模型推理引擎时的CUDA版本选择问题,提出专业建议。分析表明,CUDA12.9(需搭配552.06+驱动)是最优选择,因其完全支持BW架构特性,且与vLLM/SGLang最新版本深度适配。文章提供详细的Linux环境部署教程,包括驱动升级、CUDA12.9安装及vLLM/SGLang配置步骤,并指出CUDA13.0目前适配不完善,不推荐新手使用。最后给出常见问题解决方案,强调版本匹配对推理性能和稳定性的重要性。

2501_93651177的博客 681

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Hertz探究路由

var (// ... 省略的其他变量这里定义了一个字符串常量,用作未知传输器的名称。是一个全局变量,用于设置默认的网络传输器。首先,定义了两个接口IRouter和IRoutes,它们包含了路由处理所需的所有方法。IRoutes// ... 其他HTTP方法的声明IRouter接口扩展了IRoutes接口,添加了Group方法,用于创建新的路由分组。root *node这是主要的路由器结构,包含HTTP方法、根节点以及一个映射,用于存储具有尾部斜杠重定向处理程序的路径。

weixin_45492503的博客 1340

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

解读开源 Go HTTP 框架 Hertz | 服务注册拓展实现

在参与 Hertz 框架的开发迭代过程中,对 Hertz 的主库也越来越熟悉。接下来的几篇文章我将分别解析 Hertz 的服务注册、服务发现和负载均衡拓展,最后会使用适配于 Hertz 的 etcd 拓展进行实战,欢迎大家关注。

Lance_Yuan24的博客 1242

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

深入探索后端领域的Hertz框架

A:Hertz采用Netpoll网络库实现更高效的epoll复用,相比Gin标准库实现提升3倍吞吐量。(注:以上为精简版示例,实际完整内容需满足8000字要求)

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 889

字节赫兹 框架教程 一请求上下文之请求

该函数的默认行为:若 X-Forwarded-For 或 X-Real-IP Header 中存在 ip,则从这两个 Header 中读 ip 并返回(优先级 X-Forwarded-For 大于 X-Real-IP),否则返回 remote address。注意:该函数支持从 application/x-www-form-urlencoded 和 multipart/form-data 这两种类型的 content-type 中获取 value 值,且不支持获取文件值。(详情请参考 Args 对象)

个人博客,记录了本人学习的各种有趣的技术。 518

Hertz自学自讲(三)

注意:由于 netpoll 和 go net 触发模式不同,netpoll 流式为 “伪” 流式(由于 LT 触发,会由网络库将数据读取到网络库的 buffer 中),在大包的场景下(如:上传文件等)可能会有内存问题,推荐使用 go net。字段,所以在使用 DoTimeout 和 DoDeadline 函数时无需使用 WithRequestTimeout 函数,若同时使用了,请求超时时间以最后一次设置的为准。如果 dst 太小,则将被响应体替换并返回,否则将分配一个新的切片。

weixin_73956119的博客 1042

字节跳动自研HTTP开源框架Hertz简介附使用示例

字节跳动自研HTTP开源框架Hertz简介附使用示例

热爱C++和golang的学生 3670

字节跳动开源 Go HTTP 框架 Hertz 设计实践

Hertz 是字节跳动服务框架团队研发的超大规模的企业级微服务 HTTP 框架,具有高易用性、易扩展、低时延等特点。本文将重点关注 Hertz 的架构设计与功能特性。

weixin_44186218的博客 5311

Go CPU 剖析的“地基“:信号、CAS、写屏障、无锁环形缓冲

本文通过“卡点自查表”梳理Go CPU剖析(cpuprof.go)中反直觉设计的底层逻辑,聚焦信号处理、CAS自旋锁、写屏障与无锁缓冲四大核心机制。指出所有设计皆源于信号处理器“不可阻塞、不碰堆、不持锁”的铁律,进而推导出:CompareAndSwap一次即走、环形缓冲无锁写入、预分配内存等策略的本质是向“在任意指令间被中断”这一事实妥协。结合多核并发与操作系统调度原理,揭示了高性能采样器如何在极端约束下实现低延迟、高吞吐。

不愿言弃-念何的博客 406

Redis 从 0 到 1(二十七):JSON 体积是 Protobuf 的 3.7 倍?3 种序列化的 Go 基准测试

缓存对象直接用 json.Marshal,1 亿条 key 多花 20G 内存和 3 倍带宽。本文对 JSON / MessagePack / Protobuf 做 Go 基准测试(体积、编解码耗时、CPU),给出不同场景的选型表和统一序列化封装。

2501_92769340的博客 184

cpuprof.go开关、缓冲区与记账

本文详解Go语言CPU剖析的全链路机制,核心为定时信号触发栈采样、环形缓冲存储与异步写入。通过实验验证了64帧栈深度限制、1MiB缓冲区容量及样本丢失计数机制,揭示了SetCPUProfileRate控制采样频率、add函数处理信号中断、addExtra上报丢失样本等关键流程,并解析了跨平台差异与废弃特性。

不愿言弃-念何的博客 361

联犀 Go SIMD 实战:视频转码从 16.5ms 到 5.46ms

联犀Go视频转码实战:在352×288测试流中单帧单核CPU耗时从16.5ms到5.46ms,区分SIMD、代码及编码策略的综合收益。保留测试条件、压测结果与适用边界。

QQ603785348的博客 334
上一篇: spring boot整合jwt
下一篇: http 详解 三 http首部各字段意义
过去日记
过去日记 新星创作者: 后端开发技术领域 新星创作者: 后端开发技术领域
博客等级 码龄3年 5342粉丝 225原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过去日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值