目录
微服务这个词,倒是很熟悉了,之前也有两个项目有接触过,不过都是写业务代码,感觉写起来都差不多,这次有个重构项目,从头到尾啃一遍微服务。
一、微服务流水账
14年微服务被提出
1,微服务的特点
微服务是一种架构风格(就是说些代码的一种风格),有什么特点呢?
(1)一个大的服务是由一系列微小服务组成
(2)跑在自己的进程里,我看到的就是服务放在单独的项目或者module
(3)每个服务为独立的业务开发
(4)独立部署
(5)分布式管理
别小看这些概念,学着学着,每一句概念对应了一个技术。比如jenknis可以做独立部署,分布式管理我知道的有zookeeper,spring里的eurake也是可以做分布式管理的。
2,架构上看微服务
从架构上来看,是这么改变的:
单体架构
博主做得也是一个单体架构的重写项目,单体架构的模式大概是这样:
单体架构的优点:
(1)容易测试;
(2)容易部署;
缺点:
(1)开发效率低;一个团队都在一个项目里改代码,很容易相互影响的。
(2)代码维护困难;全部逻辑写在一个项目里,一旦有新人接手,完全不知道如何下手。
(3)部署不够灵活;这个和容易部署指的不是一个东西,比如一个项目很大,它部署起来会很慢,而且容易报错。
(4)稳定性不高;一个地方出了bug,整个系统就崩溃了
(5)扩展性不够;无法满足高并发的要求,毕竟只有一个节点;
另外一个东东是前后端分离,这个趋势日渐明显,总之感觉jsp页面以后可能都很难看到了吧。
3,分布式及微服务架构示例
啥叫分布式?
旨在支持应用程序和服务的开发,可以利用物理架构,由多个自治的处理元素,不共享内存,但通过网络发送消息合作。
为啥要提分布式呢?因为微服务就是通过分布式实现的。
一个简单的微服务架构:
看这个图大概知道,微服务需要的组件有:
(1)服务注册发现;就是能够告诉别人你的ip和提供的服务。
(2)服务网关(Service Gateway),这个东西是连接内外的大门,网关会对外屏蔽后台服务的一些细节,它有路由的功能,能将外部的请求转向到内部的具体服务;这一块也可以做安全的处理,像用户的认证、反爬虫等。可以说这个东东的作用非常巨大
(3)后端通用服务(也称中间层服务Middle Tier Service)
(4)前端服务(也称为边缘服务Edge Service)
来对比下两种方式的差别:
实际上相对于原来的架构,微服务的架构只是改变了一下实现方式。
国内微服务的方式主要有两大“配方”:
(1)阿里系:dubbo(核心,服务化治理)、Zookeeper(服务注册中心)、Spring MVC之类
(2)spring cloud:Spring cloud netflix eureka、spring boot
二、Spring Cloud
1,spring cloud是什么?
spring cloud是一个开发工具集,含多个子项目:
(1)利用spring boot的开发便利
(2)主要是基于对Netflix开源组件的进一步封装
。。。。
Spring cloud 简化了分布式开发
实际上,我们最主要的是要做到:掌握如何使用,更要理解分布式、架构的特点!
2,Spring Cloud Eureka
这个东东是基于Netflix Eureka做了二次封装
它由两个组件组成:
(1)Eureka Server 注册中心;
(2)Eureka Client 服务注册;
Eureka Serve(注册中心)
这个东东记录了所有应用的东西和状态
创建Eureka项目:
注意一下上面有个spring boot的版本
创建好了,可以把不需要的部分删掉:
ok,先来看一下pom文件:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud-services.version>2.0.3.RELEASE</spring-cloud-services.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
这里很有意思,spring boot的版本和spring cloud是不一样的!
要怎么确定用spring cloud的版本呢?
在官网找到spring cloud项目:
http://spring.io/projects/spring-cloud
这里面可以找到spring cloud对应的版本,这部分说明一下,第一列是component是spring cloud的组件,剩下的三个是spring cloud的版本。在组件里可以找到spring boot,这里就可以看到匹配的版本了。spring cloud的版本用的是伦敦地铁站的名字
然后就可以启动项目了!
idea是真的方便,啪啦啪啦就可以启动了。
但是这里遇到一个问题:
一启动,就来到这个页面,我猜想是设置了security,那我自己设置一个yml试试看:
security:
basic:
enabled: true
user:
name: admin
password: admin
没有!
后来想到原来的一个处理,把仓库清一遍,有可能是仓库间的冲突。bingo!妈蛋的,折腾了半天的问题,实际上还是依赖的事,终于可以打开了:
这个界面有几点说明下:
(1)DS Replicas
这个部分说明现有的服务
(2)registered-replicas 注册地址
为什么这里个eureka会老报错呢,因为它本身也是个client,需要进行注册
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
这时候要在属性里面配置(properties.yml):
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
这时候在应用这里多了一个东西:
再加上这一句后重启:
spring:
application:
name: eureka
应用名就有了。当然对于eureka服务而言,本身是没有必要注册的,因此加一个设置:
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
register-with-eureka: false
由于后期项目会较多,把端口改了:
server:
port: 8761
ok。eureka Sever端就基本可以了,接下来我们来看看client。
Eureka Client(服务注册)
为了方便注册,我们可以把eureka server打成一个war包
命令行:
mvn clean package
然后在target里找到jar包:
java -jar ...jar
新建项目:
这里说明一下,如果https不好访问,换成http
新建client项目,版本还是用的2.0.8:
项目新建好之后,老规矩,把不需要的部分删了:
然后先不要急着写代码,先在pom中修改版本,由于我这一套的版本和官网有点不一致,之后有可能需要修改版本。
修改了pom文件之后,用reimport,和eclipse的update很像。
启动了之后,没有注册到eureka中(当然的啦,地址都没配),在yml中配置:
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
但是还是不能注册!为什么呢?因为在入口类上没有加注解:
@EnableDiscoveryClient
这时候启动项目,client项目还是启动不了:
2019-01-23 14:44:13.550 INFO 8692 --- [ Thread-20] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@398dada8: startup date [Wed Jan 23 14:44:09 CST 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@2ef3eef9
2019-01-23 14:44:13.552 INFO 8692 --- [ Thread-20] o.s.c.n.e.s.EurekaServiceRegistry : Unregistering application UNKNOWN with eureka with status DOWN
这是为什么?可能是tomcat没加上去:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
嗯,这样就有东西了,所以这个错误就可以立马想到web-starter没有了:
给client加个名字:
spring:
application:
name: client
然后ip地址像变成hostname:
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
hostname: clientName
说明一下这一段:
这里实际上指的是eureka频繁地上线先,注册中心默认这东东是在线的,当然在开发阶段我们可以取消掉这个设置:
在注册中心中设置:
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
register-with-eureka: false
server:
enable-self-preservation: false
当然在生产环境就别这么设置了
3,eureka server 高可用
简单说就是一个eureka可能会崩掉嘛,因此就需要两个eureka服务来支撑
需要加一个处理就是讲eureka 服务互相注册就行了。
简单说起来就是yml分别有两个:
eureka:
client:
service-url:
defaultZone: http://localhost:8762/eureka/
register-with-eureka: false
server:
enable-self-preservation: false
spring:
application:
name: eureka
server:
port: 8761
第二个:
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
register-with-eureka: false
server:
enable-self-preservation: false
spring:
application:
name: eureka
server:
port: 8762
然后两个server都启起来,再把client启动:
这时候很神奇的事发生了:
8761和8762两个都有client服务
接下来听了8761:
8762还是会有这个服务!
但是client服务一旦挂了重启,8762也就注册不上这个服务了,因此我们需要给client同时注册两个服务:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
如果是3个及以上的高可用,那就两两注册就好了:
这种高可用当然是针对生产环境,开发环境的话一个就可以了。
4,eureka总结
@EnableEurekaServer
@EnableDiscoveryClient
这两个注解表示了eureka的服务和注册
它能够做到:心跳检查、健康检查、负载均衡等功能;
eureka的高可用当然要两台以上咯。
强调一点:
分布式系统中,服务注册中心是最重要的基础部分
服务发现的两种方式:
(1)客户端发现 ——Eureka
(2)服务端发现 ——Nginx Zookeeper Kubernate
微服务的特点:异构
(1)不同语言
(2)不同类型的数据库
Spring Cloud的服务调用方式
(1)REST or RPC?
(2)Node.js 的 eureka-js-client