spring cloud集群搭建(一、基础准备)
前言
近期在复习spring的时候翻出了自己githup上2018年写的springcloud D版本集成springboot1.5开发的一套用户管理架构模型,当时由于工作繁忙就丢在一边了,这会翻出来给重构下升级为springcloud F版本集成springboot2.x。
开发环境
java8
IntelliJ IDEA
springcloud Finchley.RELEASE
springboot 2.0.5.RELEASE
说明:tomcat使用内置,本地开发中,暂未部署服务器。
功能设计
本系统计划功能不仅限于:
1.用户:
1.1登录授权认证
1.2用户管理
1.3签到功能
2.系统
2.1系统信息管理
3.展示信息
3.1展示信息管理
…
其余功能不仅限于围绕这几点进行完善:
1.本地ehcache实现缓存初始化
2.数据库配置config管理、服务监控、熔断等功能
3.支持前端vue系统
…
// 待补充
架构设计
架构设计采用多层次业务分层模式,根据业务与功能拆分服务,分为common组件层、component功能性服务层、database数据服务层、service业务层以及最终的api接口服务层。详细结构如下:
涉及springcloud组件技术:
zuul服务网关
ribbon负载均衡
eureka服务注册中心
hystrix断路由
config配置中心
…
ps:关于服务架构分层好处是业务明了,而且服务独立,避免了多数据源处理,且内部服务调用方便快捷。
spring cloud集群搭建(二、实际开发)
组件开发
1.集群服务管理
集群管理采用eureka服务注册中心
eureka分为客户端client与服务端server
区别于D版本及以前版本,F版本将许多组件都放到netflix下,所以eureka的server端需引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
然后在application上加入注解:@EnableEurekaServer
配置信息如下,主要包含端口、服务名、eureka客户端地址及基础信息配置:
server:
port: 8088
spring:
application:
name: spring-framework-server
eureka:
client:
service-url:
defaultZone: http://localhost:8088/eureka/
register-with-eureka: false
fetch-registry: false
instance:
appname: eureka
说明:
register-with-eureka: false 是否注册到eureka上,肯定不注册,现在单节点
fetch-registry: false 是否从注册中心拉取注册信息,这里单节点不拉取
如果是集群则需要开启为true
启动服务端:
然后可见注册中心可视化界面信息。
然后再启动其他服务注册中心会加载到该服务:
例如zuul服务启动:
此时会将服务注册到eureka注册中心中。
2.网关过滤配置
springcloud提供了关于服务请求的访问过滤策略,同样先引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
然后在application上加入注解@EnableZuulProxy,详细配置如下:
zuul:
host:
connect-timeout-millis: 3000
socket-timeout-millis: 20000
routes:
spring-framework-user:
path: /user/**
serviceId: spring-framework-user
# url: http://localhost:9001/
spring-framework-explore:
path: /explore/**
serviceId: spring-framework-explore
# url: http://localhost:9002/
spring-framework-system:
path: /system/**
serviceId: spring-framework-system
例如上述配置,会依据服务路径的配置映射到不同的服务部署的机器上。
而过滤器则需要实现ZuulFilter进行配置并注入@Bean来加载。
方法:
@Bean
public UserFilter userFilter() {
return new UserFilter();
}
类:
public class UserFilter extends ZuulFilter {
@Override public String filterType() {
return null;
}
@Override public int filterOrder() {
// 过滤器执行顺序0-~ 先-后
return 0;
}
@Override public boolean shouldFilter() {
// 是否需要
return true;
}
@Override public Object run() throws ZuulException {
// 过滤逻辑
return null;
}
}
通过过滤器可以实现服务请求的各种基础校验,例如token、用户权限等等。
启动后服务会注册到eureka上:
3.服务熔断设置
通过hystrix进行服务断路由控制,首先引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
此服务按照实际需要可拆分为turbine、hystrix、dashboard三个服务,这里方便测试使用融合为一个服务,turbine与dashboard配合使用。
注解:
@EnableTurbine
@EnableHystrix
@EnableHystrixDashboard
@EnableCircuitBreaker
配置文件:
server:
port: 8092
spring:
application:
name: spring-framework-hystrix
eureka:
client:
service-url:
defaultZone: http://localhost:8088/eureka/
logging:
config: classpath:logback.xml
turbine:
app-config: spring-framework-user,spring-framework-explore,spring-framework-system
hystrix:
dashboard:
enable-ignore-connection-close-header: true
metrics:
enabled: true
management:
endpoints:
web:
exposure:
include: hystrix.stream
说明:
turbine.app-config配置监控的服务
management下配置的暴露的服务监控对象,这里也可以通过代码来配置。
启动服务:
此时后台会加载对服务的监控:
打开控制面板:
此时输入http://xxx:xx/actuator/hystrix.stream或turbine.stream可以看到监控界面:
后台:
此处的loading有两种原因:
1.配置失败,需要调整配置
2.未有请求发送
关于hystrix监控接口处理的话可以加入@HystrixCommand来配置。
4.配置中心设置
配置中心用来管理服务的配置,通过读取独立的配置来进行管理,首先引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
然后配置远程或本地两种配置方式:
spring:
application:
name: spring-framework-config
cloud:
config:
# 这里配置为git配置读取git路径下的配置文件
server:
# git:
# uri: https://github.com/lovezmming/spring-cloud-config.git
# search-paths: dev
# username:
# password:
native:
search-locations: E:/study/spring-framework-core/database/dev
profiles:
active: native #这里配置为本地配置,如果是用git配置则屏蔽该配置
在application上加上注解@EnableConfigServer启动服务即可。
例如本地配置:
即可看到配置:
客户端配置:
获取config配置的时候不能使用application配置文件,因为application是在服务启动期间进行加载的,需要配置bootstrap文件进行服务器启动前加载,故需要配置:
spring:
application:
name: spring-framework-system
cloud:
config:
discovery:
enabled: true
service-id: spring-framework-config
# uri: http://localhost:8093/
profile: dev
# label: master (git-master svn-trunk)
name: system-config-dev
fail-fast: true
这里指定service-id与配置的名称、环境信息,启动服务后会自动加载该配置。
业务开发
业务开发模式与常规开发基本无差。
1.api接口:
接口开发定义了接口请求与返回参数,以及内部feign请求的接口路径与服务,并指定了异常方法配置信息。
这里说下feign的内部调用,springcloud F版本已更改为openfeign,feign请求的接口是模拟进行controller接口请求的,所以要保持返回参数对象一致,请求对象可以不一致,但必须保证详细的参数是一致的,get请求必须加requestParam,post请求必须加requestBody等等。
2.业务开发:
详细的业务实现从controller开始:
此处配置使用了多环境配置:
spring:
profiles:
active: @package.env@
3.数据库相关开发:
此处使用mybatis反射生成对应的接口mapper与model:
mybatis-generator.xml配置生成器文件:
<generatorConfiguration>
<properties resource="mybatis.yml"/>
<context id="MysqlTables" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="autoDelimitKeywords" value="true" />
<property name="javaFileEncoding" value="utf-8" />
<property name="beginningDelimiter" value="`" />
<property name="endingDelimiter" value="`" />
<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<commentGenerator >
<property name="suppressAllComments" value="false"/><!-- 是否取消注释 -->
<property name="suppressDate" value="true" /> <!-- 是否生成注释代时间戳-->
</commentGenerator>
<!-- jdbc连接 -->
<jdbcConnection driverClass="${driver-class-name}"
connectionURL="${url}"
userId="${data-username}"
password="${data-password}" />
<!-- 类型转换 -->
<javaTypeResolver>
<!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 生成实体类地址 -->
<javaModelGenerator targetPackage="com.spring.framework.user.database.po"
targetProject="src/main/java" >
<property name="enableSubPackages" value="false"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成mapxml文件 -->
<sqlMapGenerator targetPackage="com.spring.framework.user.database.mapper"
targetProject="src/main/resources" >
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 生成mapxml对应client,也就是接口dao -->
<javaClientGenerator targetPackage="com.spring.framework.user.database.mapper"
targetProject="src/main/java"
type="XMLMAPPER" >
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- table可以有多个,每个数据库中的表都可以写一个table,tableName表示要匹配的数据库表,也可以在tableName属性中通过使用%通配符来匹配所有数据库表,只有匹配的表才会自动生成文件 -->
<table tableName="%"
enableCountByExample="true"
enableUpdateByExample="true"
enableDeleteByExample="true"
enableSelectByExample="true"
selectByExampleQueryId="true">
<property name="useActualColumnNames" value="false" />
<generatedKey column="id" sqlStatement="Mysql" identity="true" />
</table>
</context>
</generatorConfiguration>
mybatis.xml文件中配置数据源:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
data-username: root
data-password:
url: jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf-8&useSSL=true
执行生成对应的实体接口,满足基础接口使用,亦可以自定义接口实现:
最终就是业务的具体实现了,不赘述。
spring cloud集群搭建(三、部署发布)
部署发布这里使用docker容器,linux为centos7系统。
docker部署集群,eureka可配置多节点,一主多从,同样的业务服务都可以进行多节点部署。
docker部署方案参考之前写的文章:
关于springboot进行docker部署
…
ps:基本上一个集群服务的开发是这样完成了,但很多细节未进行描述,后续会进行修改调整完善。
code源码-githup
微信公众号:像是风