go与java

到今天我使用java语言11多年多了,java伴随我开发了很多服务器项目,伴随我开发过android,对于java我有比较深厚的感情。我开始关注go是在2017年,那时我就职于某广告公司,公司的竞价系统因为需要高并发使用go开发。

从2018年开始创业,因为java非常熟悉,市场上java程序员非常多,方便招聘,首选java开发,从2018下半年开始,毅然决然新的项目使用go开发,是什么原因让我下定决心呢?

java的运行原理很简单,把源文件编译生成一种二进制中间码,存储在class文件中,然后再通过运行与操作系统平台环境相对应的Java虚拟机来运行class文件,执行编译产生的字节码,调用class文件中实现的方法来满足程序的Java API调用。后续android为了提升速度出了其他的字节码文件,和虚拟机不在本次讨论范围
java的前身是1992开发的Oak语言,1996年1月发布JDK 1.0,1999年4月发布HotSpot虚拟机,HotSpot成为了JDK 1.3及之后所有版本的Sun JDK的默认虚拟机

go发布于2009年,可以说java是20世纪的产物,go是21世纪的产物。跨世纪了[惊!]。

切换

我2008年在学习java的时候还是个学生,是有c和c++基础的(vc写过计算机,读取手机短信这种水平)。 用了3个月的时间才大致弄明白java做的事情。 弄明白了各种关键字作用,和面向对象的机制。实际去企业开发的时候还是会遇到各种问题。而限制使用范围的关键字也只用public和private。很少用连续的继承。
2018年我带着团队学习使用go的时候,只用2周时间大家就都掌握了,能填充代码开发了。 如果你是一个java程序员,从java到go的距离只有2周时间

开发
// java
@RestController
@RequestMapping(value = "/xx")
public class LotteryController {

    @RequestMapping(value = "/xx1", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String xXXX1(HttpServletRequest httpRequest) {
        return "success";
    }
    @RequestMapping(value = "/xx2", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String xXXX2(HttpServletRequest httpRequest) {
        return "success";
    }
}

使用iris框架写个post方法

// go
// 启动文件
app.Post("/xx/xx1", controller.Xxxx1)
app.Post("/xx/xx2", controller.Xxxx2)
// --------------------------------------
// 具体文件中方法实现
func Xxxx1(ctx context.Context) {
	ctx.Text("success")
}
func Xxxx2(ctx context.Context) {
	ctx.Text("success")
}

这个简单的例子可以看出 可以看出java spring的方法是注解在实现类中的,go是通过写在代码中的更方便。而且所有入口在一个文件中更方便查找。
对于杠精来说可以不用spring注解,使用spring配置文件,或者servlet。。。。
在处理IO时java用try catch finally,finally中还得分开try catch 关闭。我早就忍不了,我都怀疑强迫症的人会无限的写下去。。。
java启个线程

new Thread(new Runnable() {
            @Override
            public void run() {
      		// do         
            }
        }).start();

而go的语法就精简很多了,启动个协程运行,只要在掉用的时候加关键字go。

通过代码我们可以看出go的代码非常精简

运行

go的协程设计确实更适合高并发,java开一个线程就对应于一个系统线程。go开一个协程不对应一个系统线程。一个系统线程内存消耗一般2M,而协程只需要2k。1k个线程是2G内存。2G的内存能放多少协程啊

go的runtime与用户代码一起打包成可执行文件,java的代码需要依赖于虚拟机,open jdk 8的jre有100多Mb呢。

go的协程没有那么神秘,可以说实现的很简单。使用G-P-M模型
G:Goroutine用于存储运行堆栈、状态和任务函数可复用,需要绑定到P才能被掉用,Goroutine会排队等待执行。
P:Processor逻辑处理器,提供执行环境,内存分配状态,Goroutine队列等。P的数量由用户设置的GoMAXPROCS决定,最大数256,P的数量决定了并行执行G队列的数量。物理CPU核数 >= P的数量
M:Machine 系统内核线程的抽象,代表真正执行的计算资源,在绑定有效的P之后,进入schedule循环,schedule循环机制是P的G队列中获取要被执行的G,M的数量由Go RunTime调整,M不保留G的状态,这样G在推出M之后,下次可能由其他的M执行
Sched:Go调度器。负责维护G的总队列,和P中存在的G队列和状态信息,创建M,清理回收M等工作

性能测试
是骡子是马拉出来溜溜
使用ab命令压测同一台机器(2C4G 操作是根据id查询数据库中的一条记录) 请求次数100000 线程数150,为了避免干扰启动go服务的时候关闭java服务,反之亦然。

java环境: spring boot 2.2.5 + mybatis 3.5.3 hikari连接池 连接数200
tomcat设置:JAVA_OPTS="-Xms256m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=128m"

java第一次
在这里插入图片描述
java第二次
在这里插入图片描述
java第三次
在这里插入图片描述
java第四次
在这里插入图片描述
java第五次
在这里插入图片描述
java的统计情况
在这里插入图片描述

go环境: iris v11.1.1 + gorm v1.9.10

go第一次
在这里插入图片描述

go第二次
在这里插入图片描述
go第三次
在这里插入图片描述
go第四次
在这里插入图片描述
go第五次
在这里插入图片描述

go的统计情况
在这里插入图片描述

说明 通过压测我们可以看出Java的第一次压测劣势非常明显,java是编译成class文件, 第一次执行需要通过虚拟机进行类加载,之后的执行可以用加载好的文件执行。所以我去掉java的第一次重新计算了一下平均值

java内存 :tomcat启动之前机器已使用内存是769M,启动之后是1.20G,压测时内存峰值1.35G,后面几次压测之后,内存回收,回到1.21G

go内存 :go启动之前机器已使用内存是768M,启动之后是775M, 压测时内存峰值804M,,内存回收,回到784M

数据项javago
总耗时平均22.36s20.77s
每秒处理数44744812
每条处理耗时33.55ms31.16ms
传输速率1044k/s1122k/s
压测过程中cpu使用率96%-99%96%-99%
启动内存占用459Mb7Mb
压测过程最高占用内存613Mb36Mb
执行结束后内存占用470Mb16Mb

性能测试部分go完胜

打包编译速度

我使用的是macOS cpu i5 内存 8G

go 编译linux下的包用时 <2s
java maven 打war包用时 20s

docker image

构建docker image 的大小与方便程度决定了上线部署的速度
为了测试都基于ubuntu镜像

数据项javago
最终镜像大小151M33.8M
操作步骤1 添加jre和tomcat
2设置环境变量
3添加war包
添加可执行文件
优化空间未知使用scratch基础镜像体积更小
2019 发生了什么

go发布了两个版本1.12 和1.13 ,从1.13开始我才觉得go能正常使用了。之前go的使用有些弊端,首先打包就是个麻烦事。1.13版本Go Modules 默认成为了Golang 官方版本原生的包管理方式,包管理问题算是画上了一个句号。
还有一件非常重要的大事,之前在国内使用某系包,都会收到墙的影响,大家都是使用github上的源代替官方源,2019go有了官方承认的代理https://goproxy.cn,引包不再成为问题。

java发布了jdk12

Shenandoah GC算法,没发布在openjdk中。G1优化1(可中断 mixed GC)G1优化2 (归还不使用的内存),可以看出官方还是想改进垃圾回收。毕竟靠垃圾回收优化养活了Zing悲哀不悲哀
2019 的双11 阿里90%的容器都使用了Wisp2,这个Wisp2的最重要的一点就是给java安上了协程。真是笑出眼泪。

后续

java的库非常全面,也很好用。java程序员非常好招聘。垃圾回收一致被大家诟病,java也一直在这方面努力。
go后发优势明显,不过在2019之前因为墙和包管理的问题,非常难用。go的轮子还没有造那么多。不过正在快速补充进来。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值