设为首页 收藏本站
查看: 1062|回复: 0

[经验分享] spring cloud 学习(5)

[复制链接]

尚未签到

发表于 2017-12-8 06:41:21 | 显示全部楼层 |阅读模式
  分布式环境下的统一配置框架,已经有不少了,比如百度的disconf,阿里的diamand。今天来看下spring cloud对应的解决方案:
DSC0000.png

  如上图,从架构上就可以看出与disconf之类的有很大不同,主要区别在于:


  • 配置的存储方式不同

    • disconf是把配置信息保存在mysql、zookeeper中,而spring cloud config是将配置保存在git/svn上 (即:配置当成源代码一样管理)


  • 配置的管理方式不同

    • spring cloud config没有类似disconf的统一管理界面,既然把配置都当成git之类的源码来看待了,git的管理界面,就是配置的管理界面


  • 配置变化的通知机制不同

    • disconf中配置变化后,依赖zk的事件watcher来通知应用,而spring cloud config则是依赖git每次push后,触发webhook回调,最终触发spring cloud bus(消息总线),然后由消息总线通知相关的应用。


  另外,spring cloud config server本身也是一个微服务,跟其它的微服务一样,也可以注册到eureka server上,让其它使用方从注册中心来发现,单纯从解决的问题/场景来看,disconf与spring cloud config server是高度重合的,很难说哪个好,那个差,只是设计哲学不同。
  但有一点,从配置变化的通知机制上看,如果有100个应用节点,都依赖于统一配置,如果修改了配置,只想让某几个节点"灰度"更新配置,spring cloud config server更容易做到,这一点相对disconf更灵活(后面会详细讲解)。
  使用步骤:
  一、在git/svn上创建一个配置项目(用于保存配置文件)
  以https://github.com/yjmyzz/spring-cloud-config-repository 这个为例,上面就放了几个配置文件(推荐用新的yml格式,对中文支持更好码)。
  application.yml里的内容如下:



demo:
title: "default title"  
  其它几个文件application_xxx.yml,里面的xxx,代表不同的profile.
  二、创建config-server微服务
  2.1 添加依赖项



dependencies {
compile 'org.springframework.cloud:spring-cloud-starter-eureka'
compile 'org.springframework.cloud:spring-cloud-config-server'
compile 'org.springframework.boot:spring-boot-starter-actuator'
}  
  关键是第2个依赖项
  2.2 application.yml



spring:
application:
name: config-server
profiles:
active: server1
cloud:
config:
server:
git:
uri: https://github.com/yjmyzz/spring-cloud-config-repository
#          username: *****
#          password: *****
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
client:
service-url:
defaultZone: http://yjmyzz:123456@server1:8100/eureka,http://yjmyzz:123456@server2:8200/eureka
management:
security:
enabled: false

  注意上面的cloud.config.server这段,里面配置了git配置项目的位置。另外:config-server服务本身也需要HA,所以本示例中起了2个实例,分别对应server1、server2 这二个profile,用不同的端口,在本机跑2个实例,以模拟高可用。
  application-server1.yml



server:
port: 8004

  application-server2.yml



server:
port: 8005

  2.3 main入口类



package com.cnblogs.yjmyzz.spring.cloud.study.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* Created by yangjunming on 2017/7/5.
*/
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}

  关键是@EnableConfigServer 这个注解。 
  2.4 跑起来看看
DSC0001.png

  可以看到2个config-server已经注册到eureka上了,然后单独浏览一下: http://localhost:8004/application-dev.yml
DSC0002.png

  已经把git上的application-dev.yml的内容输出了。

  三、使用config-server
  3.1 在之前的service-provider中添加依赖项



compile 'org.springframework.cloud:spring-cloud-starter-config'

  3.2 创建一个简单的配置类



package com.cnblogs.yjmyzz.spring.cloud.study.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* Created by yangjunming on 2017/7/5.
*/
@Component
@Data
@ConfigurationProperties(prefix = "demo")
public class DemoConfig {
private String title;
}  
  然后找一个示例服务,使用这个配置:



package com.cnblogs.yjmyzz.spring.cloud.study.service.impl;
import com.cnblogs.yjmyzz.spring.cloud.study.api.UserService;
import com.cnblogs.yjmyzz.spring.cloud.study.config.DemoConfig;
import com.cnblogs.yjmyzz.spring.cloud.study.dto.UserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
DemoConfig config;
@Override
public UserDTO findUser(Integer userId) {
UserDTO user = new UserDTO();
user.setUserId(userId);
user.setUserName("菩提树下的杨过(" + config.getTitle() + ")");
return user;
}
}

  3.3 添加bootstrap.yml 配置文件



spring:
application:
name: application
cloud:
config:
profile: dev
label: master
discovery:
enabled: true
service-id: config-server
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://yjmyzz:123456@server1:8100/eureka,http://yjmyzz:123456@server2:8200/eureka

  注意spring.cloud这一节的内容,里面指定了profile为dev,读取的git配置文件分支为master,同时允许从eureka上自动发现config-server这个实例。另外 spring.applicatin.name 即为配置文件的名称(即:application_xxx.yml) 
  3.4 跑起来看看
DSC0003.png

  说明已经从config-server取到了配置。  
  四、配置更新
  4.1 Controller上添加@RefreshScope



@RestController
@RefreshScope
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public UserDTO findUser(@PathVariable Integer id) {
return userService.findUser(id);
}
}

  这个注解,根据源码上的说法:Beans annotated this way can be refreshed at runtime and any components that are using them will get a new instance on the next method call, fully initialized and injected with all dependencies. 使用该注解后,可以在运行时直接刷新Bean,并在下次方法调用时,得到一个全新的实例。  
  4.2 手动刷新/refresh
  可以尝试把git配置项目里的application-dev.yml修改下内容,再浏览刚才的http://localhost:8001/user/1 发现内容并没有变化。
  http://localhost:8001/refresh 手动向这个地址,发一个post请求(可以用postman或 curl -d '' http://localhost:8001/refresh),可以看到
DSC0004.png
  说明demo.title这个配置项被刷新了,再浏览http://localhost:8001/user/1  可以看到有变化了
DSC0005.png
  但是这样显然不是个办法,比如有10个service-provider组成的集群,如果要1台台手动刷新,太low了(除了做配置灰度更新,可以先刷新1台这种场景外)
  4.3 集成spring cloud bus来批量刷新
  spring cloud bus目前仅支持rabbitmq 及 kafka,我们以kafka为例,先在service-provider的application.yml里,加入下面的配置
DSC0006.png

  然后依赖项里,加入:



compile 'org.springframework.cloud:spring-cloud-starter-bus-kafka'

  注:关于kafka的环境搭建,网上有很多资料,大家可以参考下。
  配置好这些后,本机启动kafka,然后再重启service-provider,就会多出一个/bus/refresh的端点,即:http://xxx:port/bus/refresh ,只要向集群中的任何一台机器的/bus/refresh发起post请求,就会同步刷新其它所有节点。原理大致就是,这台机器会发一条消息到kafka中,然后其它机器都是挂在消息总线上的,也会监听到该消息,然后刷新各自的配置。
  最后一个问题:就算有/bus/refresh,也需要有人或系统触发。这个很好解决,github或gitlab上一般都有webhook功能,可以配置在代码push时,触发一些地址的回调。
DSC0007.png
  这样,只要配置的代码提交了,就会触发自动刷新。
  注:低版本的spring-cloud-dependencies有一个严重bug,调用/bus/refresh后,会导致所有服务节点,从eureka server的实例列表中永久下线,无法自动恢复,除非再次访问某个服务的/health端点,建议使用Dalston.SR2 或以上版本。
  示例源代码: https://github.com/yjmyzz/spring-cloud-demo

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-421984-1-1.html 上篇帖子: 简单几步让网站支持https,windows iis下https配置方式 下篇帖子: windows远程桌面连接树莓派通过xrdp服务
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表