- 博客(54)
- 收藏
- 关注
原创 在线编码、格式转换
日常开发或运维会比较常遇到日志中的内容格式不直观,需要转码或格式化的情况,这时候常常是去网上搜索在线工具,不但耗时耗力,又担心不安全,于是我索性就自己搭建一个,方便自己的同时,还可以分享给需要的朋友。
2022-09-11 15:32:09 1037
原创 Go chan实现并发请求聚合功能
背景有上万台边缘机器,每台都会有多个agent客户端,并且每个agent都会同时向中心系统上报数据,由于上报数据频繁,并发量也大,每个agent都频繁和中心建立连接,导致中心压力非常大,所以需要对此进行优化,对每台机器上的agent上报数据做聚合,批量进行上报,减少边缘和中心的上报频率,从而减轻中心压力。方案边缘增加一个batch中间件,所有agent上报的数据由原来直接向中心上报变为向batch中间件上报batch中间件会聚合请求,再分批向中心上报上报的方式也由原来的同步也改为异步,agent
2022-03-06 09:54:19 852
原创 Go 并发控制、防击穿 - singleflight
背景在高并发场景下经常会有存在并发访问同一个资源,这些并发的请求参数是一样,并且响应的结果也是一样,如果每个请求都重复去查询资源,无疑会给系统带来不必要的开销,并且系统压力也会增大。为了保护资源,可以对相同资源的并发请求进行拦截,只允许一个请求去查询资源,然后将获取的资源分享给其他的请求,从而较少重复查询的开销,特别是解决缓存击穿时的并发问题。方案Go singleflightGo提供了singleflight组件:"golang.org/x/sync/singleflight"组件,可以很方
2022-02-24 22:36:27 1082 1
原创 Go 并发请求量限制组件分享
背景关于限流Go官方通过一个采用令牌池的算法的实现:golang.org/x/time/rate,但是,这个限制的是每秒的请求数,有的时候我们希望限制的是系统并发处理的请求数量,类似线程池的功能,需求如下:设置一个最大的请求处理数量,当请求超过时,后续请求将等待,直到有请求处理完后被唤醒。请求的等待时间能够指定,超出等待时间就返回,提示给客户端。等待请求的个数需要能够限制,数量超过时就直接返回,提示给客户端。设计设计思路是实现一个Ticket池(NumLimiter),每个请求首先需要向Nu
2022-01-11 21:07:12 686
原创 Go database/sql连接池 - 源码学习
引言Go内置了数据库相关的库 - database/sql,实现数据库操作相关的接口,其中还包含一个很重要的功能 - 连接池,用来实现连接的复用,限制连接的数量,从而最大程度的复用连接,提高性能,避免连接数量失控,导致资源消耗不可控。本文借Go内置的database/sql库,来一起学习如何一步步设计包含连接池的数据库组件,包括模型抽象、连接复用,以及如何管理连接数。设计模型抽象首先,我们要对解决领域进行抽象。我们目标是设计一个数据库连接组件,所以第一个对象模型很明确 - 数据库对象, 我们将数
2021-12-27 18:32:15 1217
原创 Go httptest WriteHeader无效问题
背景测试一个调用http接口时,使用了httptest.NewServer来mock一个http服务端,在验证响应异常状态码时发现奇怪问题,明明设置了异常状态码,但是http.Get始终返回的状态码都是正常的200:mockHttpSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello world")) w.WriteHeader(h
2021-11-24 23:42:42 729
原创 Go时区Parse的坑
日期解析背景当有一个日期字符串(2014-11-12 11:45:26)需要转化为Go的time类型,我们第一时间肯定会想到time包的Parse方法,指定字符串的格式layout:layout := "2006-01-02 15:04:05"str := "2014-11-12 11:45:26"t, err := time.Parse(layout, str)但是,有个容易忽略的问题,go语言默认的时区用的是UTC,而我们一般要的是本地时区,可以看一下源码:package timefu
2021-11-23 22:32:10 665
原创 Go http handler统一响应&异常处理
背景在web开发中,一般会写如下方法, 处理http的请求和响应结果:// 处理hello请求的handlerfunc HelloHandler(w http.ResponseWriter, req *http.Request) { name := req.URL.Query().Get("name") if name == "" { // name 必填判断 w.Write([]byte("name is required")) w.WriteHeader(http.StatusBadR
2021-11-22 13:06:19 2404
原创 Go推荐命名规范
Go命名规范好的命名可以提高代码的可读性,特点:统一 : 容易猜想,约定俗成简短 :容易书写(Go尤为强调)准确 :准确表达意思核心准则声明的地方和使用的地方离得越远,名字就建议越详细,相对也会越长,同样上下文没提供有效的描述也是如此。Camel命名Go推荐驼峰命名方式,不建议使用下划线(包括常量,包名)GooduserMangerUserManagerBeduser_manager单词缩写默认全大写,或全小写GooduserIDbaiduCDNidcd
2021-11-17 22:21:10 2254 3
原创 Go接口 - interface 实践
interface是GO语言中非常重要的类型,它是用来定义一类方法集,只表示对象的行为(Behavior),GO语言的接口和实现不需要显示关联(也就是常说的duck类型),只要实现了接口所有方法,就可以当做该接口的一个实现,赋值给所有引用该接口的变量,从而满足面向对象编程(OOP)中的两个非常重要原则:依赖倒置、里氏替换。也正由于这个特点,所以GO接口最佳的实践是:接口尽量的小,根据实际的需求定义的接口大小。例如:io包体的Reader/Writertype Reader interface {
2021-11-15 23:09:22 367
原创 Go 1.17泛型尝鲜
简介Go不支持泛型,但是对泛型呼声一直存在,所以Go也一直在努力支持,这次发布的1.17实际上就已经包含了泛型的功能,但是默认是不开启,需要增加:-G=3参数来开启:go run -gcflags=-G=3 main.goGo的泛型有以下应用场景例子泛化形参数组定义一个函数helloSlice,接收切片参数s,元素类型为任意类型T代码:package main import "fmt" // T 自定义类型func helloSlice[T any] (s []T) { for
2021-11-02 23:24:53 495
原创 Go数组&切片使用
声明数组:var array [size] string切片:var slice [] string差异:数组的声明需要指定“size”,如果不指定就是为切片(slice)初始化数组:var array1 = [3] string{"one", "two", "three"}var array2 = [...] string{"one", "two", "three"}array3 := [...] string{"one", "two", "three"} // 推荐:无需通过va
2021-11-01 23:09:58 153
原创 exec.Command僵尸进程问题
问题exec.Command是Go标准库提供了一个可以很容易地运行外部命令的方法,但是如果使用不当会容易出现僵尸进程的问题。僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。exec.Command执行的方法有两种,一种是直接调用Run()方法:cmd := exec.Command("ls")cmd.Run()另外一种是用start方法c
2021-10-31 21:57:38 1967
原创 Go 日志组件封装
背景Go目前流行多个日志组件:logrus、zap、zerolog、seelog,他们有各自的优点,但是使用方式存在差异, 如何屏蔽这些差异,对外提供统一的接口,减少对具体的日志组件依赖,从而方便后续组件替换?对此,我们可以增加一层防腐层,定义一套统一的日志接口,业务代码不直接依赖具体的日志实现,而是依赖抽象接口,这样就可以将具体的实现进行隔离,业务代码就不会包含具体日志组件相关的代码,当日志组件需要替换时,只要做一层适配,实现约定好的日志接口方法,就可以无缝进行切换日志组件。方案定义日志接
2021-10-28 12:44:49 1232
原创 Go最佳实践总结
title: Go最佳实践总结date: 2021-03-21 17:10:09tags: - Gocategories: - 实践总结State & Behavior面向对象编程(OOP)中,将对象抽象为两个重要的属性: 状态(State) 行为( Behaivor) GO语言是通过type来实现: 状态 (State)- 数据结构(Data structure) 行为(Behavior)- 方法(Method) interface.
2021-03-21 21:54:34 715
原创 Go正则判断包含某个单词忽略大小写
GO语言如何判断字符串中是否包含有某个单词,同时忽略大小写?!通过分析可以知道,不能简单的通过是否包含字符串来判断,例如: 字符串“kiss goodbye”,虽然是有包含good,但是并不是我们要的匹配,单词的前和后是有空格或是换行隔开,或是没有任何东西,对应的正则表达式如下:`(^|([\s\t\n]+))(good)($|([\s\t\n]+))`(^|([\s\t\n]+)): good开头或是前面是空白、换行、tab分隔($|([\s\t\n]+)):good结尾或是后面是空白、
2020-10-17 23:25:15 4330
原创 N个有序的集合合并成一个有序集合
如何将N个有序的集合合并成一个有序集合?!我们可以将集合进行两两合并,然后将结果再次两两合并,不断重复,最终合并成一个集合,实际上就只是个递归算法,代码如下:package mainimport "fmt"func main() { mock1:= []int {2,5,9} mock2:= []int {1,3,4} mock3:= []int {6,7,8} fmt.Println(mergeN(mock1, mock2, mock3)) // 输出:[1 2 3 4 5 6
2020-09-26 23:19:03 716
原创 笔记本(Electron + Vue + Element UI)
市面上笔记本软件广告太多,功能不好用,就自己动手做了一个【虾记】(瞎记,开源地址:https://github.com/itart-top/notebook),使用(Electron + Vue + Element UI),支持:1. 笔记分类2. 打重要标识3. 收藏网址、文件夹、软件,支持点击直接打开:4. 快速搜索5. 右下角最小化软件...
2020-07-19 15:14:31 523
原创 GO 协程池 - Goroutine复用、限制数量
创建一个协成复用,限制协成数量的协成池package poolimport ( "fmt")type Pool interface { Schedule(task func()) error}type pool struct { work chan func() sem chan struct{} // 计数,限制协成数}func New(size int) ...
2020-05-03 08:27:12 1413
原创 Nginx 502问题排查 - proxy_next_upstream
最近线上用户请求时不时返回502,并且没多大规律,我们的部署架构是Nginx + web应用,nginx中的upstream配置了两个web做负载均衡。经过分析web应用,出现502的时候请求并没有到达web应用,所以可以断定请求502是Nginx直接返回,查看Nginx的access.log可以查到对应的请求信息,确实返回502GET /api/app/1 HTTP/1.1" 502 ...
2019-10-26 10:43:17 9660
原创 Context超时实现
go语言中的context常用作实现超时功能,一般做法是在请求接收时创建一个有超时时间的context,然后将这个context作为第一个参数传入接下来的的调用方法中,是不是这样就好了?!当然不是,接下来在就要在需要超时限制的的地方开一个协程来执行可能超时的逻辑(例如调用第三方接口),主进程使用select来等待超时或请求结束,例如:package mainimport ( "cont...
2019-09-13 17:36:09 1025
原创 Mybatis调用存储过程异常-Non supported SQL92 token at position: 1
最近遇到一个奇怪的异常,使用Mybatis调用一个oracle的package时出现一个异常:Mybatis中xxDAO.xmlgetxxByUserId" statementType="CALLABLE" parameterType="xx.xx.xx.xxInput" resultMap="xxResult"> { call #{output, mode=OUT, j
2017-02-25 10:30:53 10405 2
原创 两行代码让Html注解中显示JSP文件路径
来源: http://www.itart.cn/article/e65b83de57714229bfb83b15306ffd27Java web开发中常用JSP作为的视图,由于目前系统几乎都采用MVC分层架构,这样会存在一个问题,用户的请求地址有的时候并不会包含JSP文件路径的相关信息,这无疑会给开发调试带来不便,特别是JSP如果使用大量include指令或标签,找起来就头疼了,在这里我提
2016-07-29 12:43:35 1176
原创 Jersey - 查看所有的RESTful明细
Jersey 支持Web Application Description Language (WADL), 可以通过http://localhost:8080/xx/application.wadl来查看所有的RESTful API, 例如:工程路径: http://127.0.0.1:8080/itartWeb.xml jersey-front-servlet
2016-01-12 09:53:03 2865
原创 Oracle 获取连接数 - 排查程序是否正确关闭连接
在Java开发时, 如果数据库连接 (Connection) 没有正确关闭, 会导致该连接一直被占用, 没有释放, 也就无法被重用或关闭, 最终会导致数据库连接的溢出, 无法获取连接, 程序也就挂了.我们可以通过以下SQL来查询当前数据库的连接数, 正常情况下连接数会保持一定数量, 如果不是并发数突然增大的情况下.select username, count(username) fro
2016-01-08 11:10:12 2867
原创 Eclipse 插件开发 - 实现外部程序修改文件后刷新功能
Eclipse在加载项目时, 会对文件进行缓存, 所以如果不是在Eclipse中编辑文件, 通过调用外部程序, 例如: 系统自带的文本编辑器, 对工程中的文件进行修改, 需要手动在Eclipse中刷新一下才能重新加载.如果在开发Eclipse 插件时, 需要通过外部程序来修改文件, 这时就需要有一个方法能自动的在执行完外部程序后刷新文件, 代码如下:IFile f = ResourcesP
2016-01-05 17:04:40 4660 2
原创 Eclipse RCP - 第一个RCP程序
Eclipse RCP (Rich Client Platform) 为Java桌面程序开发提供了一个基础平台, 基于该平台用户可以快速开发出一个具有很好扩展性的桌面程序, 我们使用的Eclipse实际上就是一个以Eclipse RCP为平台, 集成各种功能的插件的一个开发工具, Eclipse RCP的核心组件:OSGI, Java语言的动态模块系统, 它为模块化应用的开发定义了一个
2015-12-31 11:31:49 12976 1
原创 异常管理 - 采用模板方法优化try-catch-finally
Java 处理异常的语句try-catch-finally应该大家都不陌生, 程序中很多地方都会使用到, 比如IO操作, 对文件的读写, 数据库读写等, 另外事务处理也会用到, 在try块中处理逻辑, catch中回滚事务 ,finally中提交事务, 举个例子:FileReadDemo.javapublic class FileReadDemo { public void readFi
2015-12-24 10:23:57 2722
原创 异常管理 - Java异常处理分析 (Unchecked Exception VS Checked Exception)
Java异常指定是程序在运行过程中出现错误或异常, 超出程序处理范围, 一旦出现异常, 如果不处理, 就没有必要继续运行下去, JAVA有两种类型的异常检查异常 (Checked Exception)检查异常类继承java.lang.Exception, 必须明确的捕获(Caught)或propagated(传播), 需要显示的调用try-catch-finally 或 throw
2015-12-23 15:55:24 542
原创 异常管理 - try-catch-finally异常信息丢失
Java在使用try-catch-finally时,如果在finally中也包含try-catch时, 如果第一个catch到异常后抛出, 由于finally不管是否出现异常都会执行, 这时在执行finally代码块时,如果也出现异常抛出, 程序只能捕获到第二次出现的异常, 而第一个异常就会被覆盖, 从而无法捕获到错误信息, 例如: public class ExceptionHandl
2015-12-23 15:35:34 1674
原创 Eclipse 插件开发 - The resource tree is locked for modifications
The resource tree is locked for modifications.
2015-12-22 09:51:23 2540 1
原创 Eclipse 插件开发 - 工具栏(tool bar)增加下来菜单
在开发Eclipse 插件时, 想在工具栏中增加一个按钮图标是非常容易, 但是想在图标上增加子菜单就会比较麻烦, 例如想实现如下效果: 具体步骤如下:首先在扩展点org.eclipse.ui.commands中增加三个指令<extension point="org.eclipse.ui.commands"> <command
2015-12-20 16:55:27 5174 3
原创 Jersey中Json与Java对象转换处理
关于Json与Java对象转化的组件除了Json-lib(http://json-lib.sourceforge.net/), 还有一个是Jackson(https://github.com/FasterXML/jackson), 使用Jackson可以很方便的处理Json和java对象之间的转换, 使用方法:在工程中引入Jackson对应的Jar包. com.fasterxm
2015-11-19 19:17:01 1428
原创 Java+mybatis+spring中读取BLOB类型异常
在查询包含BLOB字段的对象时可以正常查询出来,但是在调用以下代码时报异常:((Blob) attachment.getContent()).getBinaryStream();异常信息:java.sql.SQLException: You cannot invoke other java.sql.Clob/java.sql.Blob methods after calling the
2015-11-01 11:01:41 1265
原创 Java接口类只能声明静态属性
Java的接口在声明属性时会发现一个很奇怪的现象, 可能大家在很多地方都会看到这样的描述: 接口类中的只能有静态的属性, 但是在实际写代码中你会发现, 可以在接口中声明一个不是静态的属性, 并且不会报错, 如下:TestInterface.java package top.itart;public interface TestInterface { public String
2015-09-15 10:19:04 5495
原创 Java获取某个月的天数
不同的月可能有不同的天数, 有的是30天, 有的是31天, 对于二月的天数判断还得先判断是平年还是闰年, 所以如果自己写代码判断会比较麻烦, 其实java.util.Calendar中已经提供了获取天数的方法, 代码如下:DateUtil.javapackage top.itart;import java.text.ParseException;import java.text.
2015-09-07 09:44:46 2151
原创 Java获取时间范围: 当前季度,上个季度,昨天,当前月,上个月
Java中获取当前季度的时间范围, 上个季度的时间范围, 昨天的时间范围, 当前月的时间范围, 上个月的时间范围: DateUtils.java package top.itart.blog.common.util;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.D
2015-09-06 15:20:49 26672 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人