自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(257)
  • 资源 (8)
  • 收藏
  • 关注

原创 Golang使用CopyIn进行批量创建,提高插入效率

1. golang使用copyin方法提高批量插入效率。2. copyin对json.Rawmessage插入jsonb类型的插入方式。

2023-07-10 23:59:33 390

原创 【go-postgres】在go中,实现自动分表

go-postgres 自动分表的实现

2022-08-09 09:57:29 1370 1

原创 【架构认知】关于提供无状态的网关入口的必要性

业务机器只开放80和443,仍旧存在风险。具体体现在,非法攻击,建立了对80的连接,这个连接大概率是个nginx,nginx内部的转发确定,是有端口开销的。也就是会有明显的open file数量上升问题,引发连接数瓶颈。......

2022-07-25 11:07:58 797

原创 解决方案(19) 基于go-gin框架进行服务低成本迁移

前言对服务进行拆微的过程中,有以下问题需要考虑:拆离前后,旧服务要继续保持可用性。不能出现通知业务下游全体修改调用方式。拆离前后,代码低耦合。不能出现业务代码侵入。拆离过程,可以按照【单个接口】【某组接口】进行分块拆离。拆离过程可复制,简单,可复用.最后,整个拆离过程,需要结合团队正在使用中的框架,进行综合考量。本次方案的执行背景是,对 xxxapisrv内的业务服务,抽离出 leafsrv, 原xxxapisrv成为proxy。团队语言是go,框架为gin期望效果接入前r.POS

2022-04-15 17:04:21 851

原创 解决方案(18) 自建数据库和云数据库无损迁移方案

前言从自建数据库到云数据库的无损迁移方案的设计和实行,是基于以下背景:在服务流量比较少时,多个模块共服务,共数据库。qps起来后,发现数据库因为热点流量,出现了读写瓶颈。在迁移时,数据库选型为自建还是云数据库。因为运维能力在dba层面比较薄弱,暂时不考虑继续维护数据库生态,而使用云厂商的云数据库组件维护,而旧数据源是使用了自建数据库。并且,云数据库不开放定制化双写设置,内部的迁移计划粒度,也无法细化到某个表,并且做不到业务无损。迁移过程,业务方期望用户无感,流量无损,不接受停机。PS: 方案数

2022-04-01 14:26:41 708

原创 golang 按照某个字段分表

golang按照字段分表建表

2022-03-21 10:55:07 1095

原创 Golang基于Redis实现分布式读写锁

package redistoolimport ( "github.com/fwhezfwhez/errorx" "github.com/garyburd/redigo/redis" "time")type RedisRWMutex struct { key string maxlocksecond int // 锁定状态标记的最大时间 maxretryTimes int // 最大阻塞重试次数 retryInteval

2022-03-07 10:02:33 1132 1

原创 【场景实战】 头像违规的审查场景

介绍应用app,同时发布了多种渠道, 包括但不限于 微信小程序,安卓商城,苹果商城等游戏内,玩家有头像地址。问题链路微信小程序渠道,存在用户头像违规,扣除了app应用信用分。分析: 考虑对玩家头像入库时,接入第三方头像检查,头像审核通过后入库。对历史头像,晚间依次审核,不通过的更换为降级默认头像,并通知玩家修改。接入第三方头像检查后,发现,在第三方检查验收通过的头像,在微信内依旧定义为违规。也就是,不同的渠道,他们的图片检查,有自己的标准。分析: 需要确定每个渠道的检查通道,对有通道的

2022-02-17 11:52:24 955

原创 Golang 增强版waitgroup

前言目前,golang官方的sync.WaitGroup,只有同步作用,缺少了对子任务执行的结果上下文信息。特此,设计了高仿sdk wgx,目前已投入线上使用介绍wgx 是对sync.WaitGroup的增强版,解决sync.WaitGroup的以下问题:sync.WaitGroup只确保子任务被执行,无法传递任务最终的执行结果。wgx支持三个执行结果[全失败,全成功,半失败半成功]。sync.WaitGroup不关注子任务的上下文细节,也不关注失败和成功的计数。wgx支持对失败的任务,进行上

2022-02-16 15:13:37 290

原创 Redis 分布式锁

// 阻塞等待直到可用。失败时retryInterval间隔后重试,重试次数超过maxRetry后返回// true 放行// false 已达最大重试次数,仍然拿不到锁,建议打回。func LockTil(conn redis.Conn, key string, seconds int, maxRetry int, retryInterval time.Duration) bool { if Once(conn, key, seconds) { // 放行 return true }

2022-02-11 10:23:20 548

原创 解决方案(17) 无回滚更新

前言当前服务节点集群化架构,一个应用在发布期内,存在多个节点, 发布过程持续过久(30分钟以上)。发布新版需要发布30分钟,基于tag回滚也需要这么长时间。这个在试错上的成本非常大。核心的问题在于,发版前的服务,和发版后的服务,不能共存。引入【灰度服务器集群】, 将【正式服务回滚部署】优化成【旧服务流量切换】。该方式和原方式相比,差异在:新旧服务共存。验收通过以前,只有灰度是基于新tag发布,正式服一直是旧tag。流量切换没有时间开销。回滚部署,要部署很久。如果可以发布前的节点,和发布后的节

2021-12-22 10:57:50 525

原创 解决方案(16) 异步落库方案

前言为了解决db写入pqs过高的问题,我们在db和业务之间,隔离了一层mq。实际结果,哪怕接入了mq,消息消费也跟不上,依旧负载很高。如果降低mq pull频率,那么业务实时性会降低,这个不太接受。为了解决这个场景,决定从【业务实时性】【降幂】【方案易用和复制】多个角度,设计了这一套异步落库方案。方案的主题是,将第一手数据,从db改到redis。延长redis失效时间。确保晚上能够正确执行同步。目前,线上使用稳定。分析● 【业务实时性】从实时上考虑,异步写入方式,使用mq削峰后,仍旧很高qps

2021-11-29 17:29:24 1292

原创 Golang 导出Excel下载,文件下载

import "github.com/360EntSecGroup-Skylar/excelize"func httpexcelDonwnLoad(c *gin.Context) { f := excelize.NewFile() f.SetCellStr("Sheet1", "A1", "报名时间") f.SetCellStr("Sheet1", "B1", "玩法选择") f.SetCellStr("Sheet1", "C1", "电话号码") f.SetCellStr("She

2021-11-29 16:21:40 1219

原创 golang 通过反射进行json解析

前言在某些框架里,为了和实际模型解耦,可能需要用到反射原写法var ui UserInfojson.Unmarshal(buf, &ui)ui.SyncToDB()反射写法 // o的类型为interface。在运行时,传递进来的是实例,而不是指针。 t := reflect.TypeOf(o) if t.Kind() == reflect.Ptr { //指针类型获取真正type需要调用Elem t = t.Elem() } inst

2021-11-18 19:15:46 1027

原创 linux 安装JDK8

yum -y install java-1.8.0-openjdk-devel.x86_64vi /etc/profile# 增加以下环境变量,通过上述yum安装的javahome小版本可能需要手动校对,以实际为主# javaexport JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el7_9.x86_64export PATH=$JAVA_HOME/bin:$PATHexport CLASSPATH=.:$JAVA_HO

2021-11-04 18:52:45 143

原创 golang 找不到目录则创建

_, e = os.Stat(dirpath)) if e != nil { if os.IsNotExist(e) { if e := os.Mkdir(dirpath, os.ModePerm); e != nil { fmt.Println(fmt.Sprintf("%v\n%s", e, debug.Stack())) return } } else { panic(e) } }

2021-10-26 17:57:18 905

原创 【最佳实践】一个缓存设计,让团队的效能得到了明显的提升

前言在互联网后端架构中,缓存是一种非常常见的解决方案,它有效解决了以下场景:请求数过多,打垮数据库,缓解数据库压力。降低调用第三方api出错率。某些极端场景下,有效可靠的降级方案。缓存的设计和实现,在架构上一般可以分2级。为什么不做3级,如果觉得有必要做,可以做,但是目前这种场景还很少。正文一级缓存,最常规的方案,就是Redis。Redis是分布式一级缓存,多api节点可以共用redis,使得缓存源一致。一级缓存作用显而易见,是为了缓解数据库压力。二级缓存,是api节点内存。二级缓存的作

2021-10-26 14:53:23 342 1

原创 解决方案(15) go后端,解决跨域问题

前言跨域问题在前后端对接十分普遍。之所以立为解决方案,是因为历史原本的解决跨域的问题,没有效果。实现import "github.com/gin-contrib/cors"func AllowAll() gin.HandlerFunc{ cfg := cors.Config{ AllowMethods: []string{"*"}, AllowHeaders: []string{"*"}, AllowCredentials: false, MaxAge:

2021-09-18 19:30:39 1536

原创 解决方案(14) golang pprof接入业务同端口

前言声明: 本文不对pprof基础做讲解,详情可以查阅 https://studygolang.com/pkgdoc 找到net/http/pprofgolang pprof官方介绍里,是采用了默认6060端口,单独开辟了应用进程的pprof服务。它在生产中有以下问题:需要额外维护不同应用组的pprof端口。(实际上,它可以和业务绑定在同一个路由端口里,减少端口冲突维护)。在二次开发上,可能想接入鉴权,限频的拦截,官方提供的方式做不到。官方的路由是f(w http.Writer, r *http

2021-08-20 11:20:28 816

原创 解决方案(13) 给git命令添加团队级约束。

前言本文,不对git基本命令作描述。适合群体是1年以上的it从业人员。Git-flow 是git工作流,维护了不同团队在git上的工作流。目前,Git管理,有以下问题:git-flow的样式过多,官方没有约束好,主流推荐的flow方式,导致不同团队git-flow,群魔乱舞,各自有各自的用法。(实际上,它应该有一个最优的flow,作为官方推广。)搜索团队git管理,用法。匹配到的搜索结果,全是基本命令,答非所问,不是一个git管理者想要搜到的东西。本文,从应用场景的角度,对当今git最常见的问

2021-07-03 19:05:34 126

原创 解决方案(12) 跑马灯优雅实现

前言跑马灯,是一个比较典型的业务场景。最常见的样式如:恭喜玩家[爱唱歌的李三]在[迎新杯]中,荣获第一名,获得奖励钻石*200, 现金*4元在设计和实现过程中,我们需要考虑以下问题:如何保证每个人都能拉到结果。(定期拉取还是广播推送)如何保证每个人拉取到的结果,不会重复。(如何保存用户已经观看过的记录)跑马灯如何防止无限积压,导致拉取过大。以及复用性问题。为什么要单独把这个需求,当作是解决方案来归档。因为这个场景,确实很容易被开发人员做得很烂。分析取我见到过的解决形式来分析。

2021-06-28 11:07:00 514 1

原创 解决方案(11) redis切面操作

前言基于某些场景,我们需要对项目内redis操作,进行切面操作,他包括但不限于:高频同key熔断,防止组员死循环写蹦redis集群。错误收集,对conn.Do("set","uname","tommy","a wrong arg")类回避错误的写法,能够收集到错误信息。统计实时redis流量总之,在某些时候,我们需要对redis操作,进行切面化运作。在实现这种场景时,我们必须保障:不侵入或极少侵入业务代码。拓展灵活。声明本次的解决方案,仅解决golang下github.com/ga

2021-04-27 23:30:41 521

原创 解决方案(10) golang错误处理

前言Golang在错误处理上,没有形成良好的规范,导致真正用好的人非常少,大部分golang开发人员(哪怕是3年+)在错误处理上,依旧无法避免以下问题:1.单条错误链路过长。err.Elem("用户模块").Text("用户查询信息异常").Stack(debug.Stack()).Attach(map[string]interface{}{ "url": c.FullPath(), "param": param, })2.同种错误,多次处理。control/login

2021-04-17 19:55:54 724 1

原创 解决方案(9) 分布式的本地缓存、二级缓存

111

2021-04-10 14:51:27 585

原创 如何通过openwrite进行一文多扩散

前言本文,仅作为验证openwrite发布成功示例,介绍了通过openwrite发布流程的记录。http://admin.openwrite.cn/ 前往官后台注册并登陆按照首页说明,使用chrome浏览器配置插件。认证和配置需要接入的渠道。新建文章,发布本文由博客群发一文多发等运营工具平台 OpenWrite 发布...

2021-04-06 23:04:08 151

原创 解决方案(8) golang里的切面操作--AOP

SEO优化golang如何进行AOP操作如何给逻辑接入中间件如何设计仿gin中间件框架gin的中间件是如何实现的前言做golangWeb开发,我们都用过github.com/gin-gonic/gin。在http的gin里,可以通过以下方式,实现gin的中间件订制:r := gin.New()r.Use(gin.Recovery())它很方便地将业务逻辑handler,通过c.Next和c.Abort达到了AOP的效果。那本文章,对以下场景,提供解决方案:项目使用websock

2021-04-06 21:59:42 7835 3

原创 解决方案(7) golang话费充值多渠道兜底

前言golang在对接话费充值这一块时,一定会选择同时接入多个渠道。这是基于以下原因:有的渠道便宜,有的渠道很贵。有的渠道对移动/联通/电信手机,不支持,或存在极大的失败率。渠道的不可靠性,需要我们同时接入多个渠道。接入多个渠道,预先定好谁先谁后,然后写充值和回调逻辑,不是很简单吗,为什么特意形成解决方案?这是因为:我们接入新的渠道时,不应该侵入历史接入的渠道业务代码。以前接入渠道的人,可能离职转岗,总之做了交接。充值渠道的价格浮动,可靠性浮动,可能需要变更优先顺序,这个变更操作不应

2021-04-02 11:28:27 1730 4

原创 解决方案(6) http-gin的使用

介绍HTTP服务框架,简单易用。简称类型含义rgin.IRouter路由器对象。c*gin.Context请求上下文。paramParam路由handler的入参绑定对象1. helloworldpackage mainimport( "github.com/gin-gonic/gin")func main() { r :=gin.Default() r.GET("/weather", func(c *gin.Cont

2021-03-19 10:48:48 424

原创 解决方案(5) 代码生成

前言利用模版生成,来对常见的重复的编码,进行一键生成。使用代码生成,解决的是以下问题:大幅度减少开发时间,将常见工作过程流水化。降低新人使用门槛。减少后台和前端的对接时间。减少重复劳动里容易出错的概率。代码风格统一。代码生成最常见的业务场景:CRUD业务缓存xml转gojson转goprotobuf转goproto-rpc转go1. 业务流程1.1 生成业务模型与缓存支持import mc "github.com/fwhezfwhez/model_convert"

2021-03-16 14:28:50 328

原创 解决方案(4) 熔断保障

前言服务间调用,作为客户端的一方,必须防止服务不可用,而造成客户端服务崩溃,引发雪崩。调用方必须对每一个不可靠的服务调用,做到【熔断】机制。【熔断】: 当某一个请求单位时间内,失败次数达到阈值时,该类请求进入熔断状态。熔断状态下,后续请求将直接返回错误,而不会真的去请求等待超时。熔断状态存在持续时间。【熔断的作用对象】: grpc服务调用的客户端角色, http服务调用的客户端角色, tcp服务调用的客户端角色。分析可以基于redis实现分布式熔断器。可以基于单点实现熔断器。熔断操作必须

2021-03-09 20:01:37 943 3

原创 golang限制某一个方法,同一时间只能被执行一次

单点func f() { rs := atomic.AddInt32(&a, 1) defer atomic.AddInt32(&a, -1) if rs != 1 { return } // handle your job}分布式func TomorrowZero() time.Time { ts := time.Now().AddDate(0, 0, 1).Format("2006-01-02") tz, _ := time.Parse

2021-03-08 17:07:13 1187 2

原创 解决方案(3) 协程保障

前言goroutine是golang的重点特色。由上层语言自实现的协程概念,在使用者层面,他的作用等价于线程,但是使用者不需要关注线程资源,线程调度,线程模型等底层原理。使用一个go协程也非常简单go func(){ fmt.Println(111)}()尽管他的设计和实现都非常轻量,但是在实际团队项目里,因为错误的协程使用,仍然会给团队带来不少隐患,相信大家都遇见过以下问题:发现了内存泄漏问题,继而定位到了数量爆炸的goroutine数量。因为想要在业务里,增加一段其他业务的异步

2021-03-06 10:32:04 254

原创 windows 不支持wget命令怎么使用命令行来下载

curl https://下载地址 > 安装文件名

2021-03-04 09:32:09 517 1

原创 解决方案(2) 分布式二级幂等

前言api服务里,幂等场景在【写入】场景非常重要。它包括了:修改任务进度领取奖品充值……幂等的作用,是防止某一次操作,在并发调用时,意外地执行了不止一次。(理论上,不论执行多少次,执行结果,都应该和一次相同)幂等的实现往往围绕某一个key, key具备一定的业务含义:基于路由规则/x/xx/x/ 和接口限频有关基于用户id 和用户请求限频有关基于订单id 和充值相关幂等是如何保障【写入】场景的安全的以基于订单id的幂等为例。用户凭借订单id来获取道具,同一个时间

2021-02-18 17:23:00 171

原创 Redis 定长队列(支持redis集群)

前言某些业务场景,需要实现原子性的,性能可靠的分布式定长队列,它必须具备以下功能:队列具备失效期。队列最大长度为n,并且当元素满了时,拒绝添加新数据。队列最大长度为n,当元素满时,弹出最早的数据,接受新的数据。分布式api可以低成本接入和使用。实现考虑使用redis来实现源码package redistoolimport ( "github.com/fwhezfwhez/errorx" "github.com/garyburd/redigo/redis")// 定长lis

2021-02-07 15:40:39 3808

原创 解决方案(1) redis单点切集群(腾讯云redis-cluster)

背景为了应对更多的流量冲击,决定将业务的redis迁移到集群里。后端应用是golang开发的。源: 单机redis目标: 腾讯云redis集群3主0从条件: 集群redis内已有数据,非空迁移经过1. DTS先采用腾讯云官方的DTS切换方案,失败。失败原因: DTS只支持节点数据迁移到空集群。2. 决定重构redis组件,按照下述流程完成迁移第一步,所有应用双向写入源和目标redis,读写返回值取源返回值。第二步,保持15天+。确保未同步的缓存正常失效,新缓存全量同步。第三步,所

2021-02-05 16:15:26 267

原创 Rocketmq常见问题

rocketmq使用过程中,踩过的坑,以及注意事项, 以及最佳实践

2021-02-04 17:04:54 1707

原创 golang sha256withrsa

前言华为支付用到了sha256withrsa,百度了很多都不行,特地手敲了一个。实现package sha256WithRsaimport ( "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "github.com/fwhezfwhez/errorx" "strings")func Sha256WithRsa(p

2021-01-25 16:22:33 861

原创 golang 限流

golang 如何对高并发的场景进行限流import "golang.org/x/time/rate"// 每秒最多30次放行var l = rate.NewLimiter(1, 30)func TestExecLimit2(t *testing.T) { runtime.GOMAXPROCS(runtime.NumCPU()) go func() { for { ExecLimit2(l, func() { fmt.Println("do") }) } }

2021-01-20 16:52:51 481

原创 rocketmq 消息出现 NOT_CONSUME_YET

问题data-srv测试服存在消息,一直处于NOT-CONSUME-YET状态,几率很大。排查过程检查订阅sdk,确认是否回复ack.√• 修正订阅时,拉取到多个msg时,只处理一个handler的问题。 该bug不会造成not-consume。• 修正路由注册时,可能造成subscirbe同一个topic/tag多次的问题。 该bug不会造成not-consume。• 确认了已经回复了ack。检查consumergroup,是否存在订阅关系不一致。.√• 检查了消费方的消费组名,都叫GI

2021-01-18 11:16:26 11212 1

protoc-3.8.0-win64.zip

内涵protoc release,包含protoc.exe,版本为3.8,包含google/protobuf包

2019-06-11

markdown使用实例

博客:http://blog.csdn.net/fwhezfwhez/article/details/79282252 的编辑源码

2018-02-07

JMeter文件夹解压直接使用

JMeter文件夹,解压即可使用,JMETER.bat双击即可出现图形界面,操作方法见博客

2017-12-27

workbench免安版

win7 64位下的workbench完整压缩,打开workbench.exe可使用

2017-12-27

struts-2.5.10

struts的完整包,把主jar添加进工程的build path可直接使用

2017-12-27

hibernate5.1.0完整包

所需的关键jar在文件下/lib/required里,添加进工程build path可直接使用

2017-12-27

mybats-3.1.1

mybatis-3.1.1整体 主jar包添加到工程build path里即可使用

2017-12-27

mysql驱动包,mysql-connector-java-5.1.16.jar

用于配置连接mysql数据库资源的主jar包,在java工程里可以把他放入lib里,添加进build path,web工程可以放入web-inf的lib里~~~

2017-12-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除