月度归档:2018年08月

spring cloud学习笔记

早在16年,部门都尝试过使用Spring boot来搭建项目,实现一些小功能和业务,对于spring cloud也只是表面上的了解,没深入去学习过,这几个月还算比较系统学习,不过迁移成本实在太高,只能放弃,如果说后台团队在8-10人,我想迁移还是值得的,至少能让同事们学习到更多先进的东西,理解它的思路,包括如何使用docker去构建环境,去部署项目。

spring cloud并不是新东西,只是把很多需要的三方框架优化并整合到一起,核心基础是spring-boot,micro service之间是消息通信,如何高效通信,然后就有了注册-发现机制,所有的provider都注册到service discovery component上,这类支持有eureka,consul,zookeeper等,主要功能就是服务注册表,服务注册与发现,服务检查。consumer要调用provider就通过eureka等这类组件。服务要集群部署则可以通过ribbon在consumer实现负载均衡,通过一定规则或者自定义规则调用指定服务名的provider,如果service要提供rest api给consumer,通过feign即可。

不能让用户或者客户端去零散的调用微服务,使用统一网关是必要的,如zuul,不仅能统一服务,还能直接使用过滤器来筛选,提高效率。

如果上大型集群,使用config来统一管理微服务配置,直接配置git连接,总之就是方便。

要监控服务和容错处理则使用hystrix即可,内置rabbitmq兼容,还带有dashboard,实时监控,还有sleuth+zipkin,这种就高级了,实现分布式跟踪。

还有更高级的特性暂时也没细研究,利用spring boot + consul/eureka + ribbon + zuul + hystrix + config 已经可以实现足够强大的微服务后台,而且很简单,复杂的已经被实现,对于我们只需要在于业务方面,如何设计,如何拆分细粒度,松耦合等。不过对于人员的基础要求还是相对高点,现在云南这边大部分培训出来的就整点spring mvc完事,boot都未必接触,分给每个人一个服务,实际上是一个独立的模块,很难控制他的代码质量,增加代码审核成本,像我们现有项目,实际上拆成了4,5个,后台有独立common,service,controller,web,mq等,对于初级点的程序员,我只给controller项目即可,照着设计好的接口文档调用service返回json,供app,node层使用。如果说上cloud,至少来说一个微服务得两人来做,或者一个人一个微服务,然后两三个微服务一个负责人。

我看node也有实现的eureka-js,就是说也可以用node写微服务,供客户端调用,使用sidecar整合。

下个项目想整下这套解决方案,培养一堆相对比较厉害的程序员出来。

另外就是看了两本书,聊聊架构,进化,前者真的是太差了,通篇废话,做架构整成了哲学,什么是架构,什么是产品,我也实在无语,还挺贵一本。另外就是技术相关书籍国内作者和国外差的不知道哪去了。

iOS读书笔记

最近更新iOS版本6米网,顺便看了几本iOS的书,iOS面试之道和iOS开发进阶,个人觉得也就是个入门,相比早年看的objc的书还有cocoa编程,设计模式等书,这两本还是差强人意,还以为有很深入的讲解,其实大部分都是点到为止,还带很多工具介绍,上架介绍等教程,其实没这必要,少贴点代码,多让人去搜索学习更好,比如之前看过的java程序员修炼之道,我就觉得挺好,讲的系统,很多干货需要下来google下,没有那么多琐碎的代码。

Go语言学习笔记

昨天忙完抽空花了点时间在https://golangbot.com/learn-golang-series/ 学习Go语言,环境我是早搭建了,也就写了个HelloWorld。昨天在那个教程上学习了1-17,整个语法感觉还是很像C语言的,唯一让我觉得怪异的就是类型后置,不过这是都是基础,go的核心是在并发处理上,接下来往后学习相关教程,顺便看看https://github.com/ethereum/go-ethereum,早日上手区块链相关。

 

8月17日增补

昨天小程序已经上线,今天打算利用一天时间学完整个golang教程,为下一步区块链做准备。学完基础倒是没觉得有什么特别的,学到concurrency和oop这两章,OOP的三大特性:封装,继承,多态。golang使用自己的方式实现了,struct实现封装,继承。struct里面可以套用匿名struct这算是go的一种特性。对于多态,则使用interface实现掉。

对于并发核心就是goroutine,降低了并发的开发成本。使用go关键字就new了一个goroutine,或者说是一个线程。主函数就是在一个单独的goroutine中运行,即main goroutine。这就有点像iOS的runloop,不过iOS是消息驱动类型的,runloop作用是获取消息和处理事件。题外话,node不就是事件驱动,单线程非阻塞,eventloop获取event,到event handler,处理完成继续event loop。不过node其实是支持多进程的cluster,另外非阻塞实际上IO,异步都是在内部子线程处理。

  • Goroutines are extremely cheap when compared to threads. They are only a few kb in stack size and the stack can grow and shrink according to needs of the application whereas in the case of threads the stack size has to be specified and is fixed.
  • The Goroutines are multiplexed to fewer number of OS threads. There might be only one thread in a program with thousands of Goroutines. If any Goroutine in that thread blocks say waiting for user input, then another OS thread is created and the remaining Goroutines are moved to the new OS thread. All these are taken care by the runtime and we as programmers are abstracted from these intricate details and are given a clean API to work with concurrency.
  • Goroutines communicate using channels. Channels by design prevent race conditions from happening when accessing shared memory using Goroutines. Channels can be thought of as a pipe using which Goroutines communicate. We will discuss channels in detail in the next tutorial.

对于channel,就是读取写入阻塞的队列。select就是多个阻塞队列任意又一个不再阻塞,select就会被执行。mutex就是互斥,和channel搭配使用。

f() //普通阻塞方法
go f() //创建一个新的goroutine然后执行该方法

ch := make(chan int) // 可以写入读写int类型的channel ch <- x //写入 ch = <-ch //读取 <-ch //读取并直接舍弃 func hello(done chan bool) { fmt.Println("Hello world goroutine") done <- true } func main() { done := make(chan bool) go hello(done) <-done fmt.Println("main function") }

defer 表示延迟方法延迟到return之前最后执行,不过如果是defer stack(defer列表),按照last in first out原则。自定义error,使用struct+interface即可。panic主要是用于抛出异常,recover则是捕获这个异常并进行处理,两者必须在同一goroutine中,如果defer a()中加个recover方法,recover方法必须使用defer调用,否则无法捕获,然后 go b()中抛出一个panic,这是无法捕获的,此刻程序就会终止掉。class function则是很像iOS中的block。reflection以为着我们能在运行时获取一个struct的所有变量的type,value。这是高级语言的特性,java,iOS都有这块,不过iOS是要基于runtime获取,java的反射则是spring的基础。

学完了教程,感觉go这块用在后台开发实现高性能是很容易。