首页 文章 精选 留言 我的

精选列表

搜索[SpringCloud],共1289篇文章
优秀的个人博客,低调大师

SpringCloud微服务实战(六)-统一配置中心

1 统一配置中心概述 为什么需要统一配置中心 2 Config Server 直接运行报错,因为会从 git拉取配置文件 在 Git 建立新仓库存放配置文件 配置 Git 信息后,重启成功,无报错 访问配置文件yml 格式 properties格式 json格式 若故意将 yml 格式写错,则会报错 两种配置文件访问路径 /{name}-{profiles}.yml /{label}/{name}-{profiles}.properties] name 服务名 profiles 环境 label 分支( branch) 新建一个分支 修改下配置文件,以示区别 访问成功 git默认存放路径 亦可自定义路径 3 Config Client 在 order 添加 config-client 依赖 配置文件修改,删除多余信息

优秀的个人博客,低调大师

springcloud之自定义简易消费服务组件

本次和大家分享的是怎么来消费服务,上篇文章讲了使用Feign来消费,本篇来使用rest+ribbon消费服务,并且通过轮询方式来自定义了个简易消费组件,本文分享的宗旨是:自定义消费服务的思路;思路如果有可取之处还请“赞”一下: Rest+Ribbon实现消费服务 Rest+轮询自定义简易消费组件 使用Scheduled刷新服务提供者信息 Rest+Ribbon实现消费服务 做为服务消费方准确的来说进行了两种主流程区分1)获取可以服务2)调用服务,那么又是如何获取服务的并且又是通过什么来调用服务的,下面我们来看一副手工图: 手工图上能够看出消费方先获取了服务方的真实接口地址,然后再通过地址去调用接口;然后对于微服务架构来说获取某一个类ip或端口然后去调用接口肯定是不可取的,因此微服务中产生了一种serviceid的概念;简单流程介绍完了,下面通过实例来分析;首先添加依赖如: 1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-web</artifactId> 4 </dependency> 5 <dependency> 6 <groupId>org.springframework.cloud</groupId> 7 <artifactId>spring-cloud-starter-eureka</artifactId> 8 </dependency> 再来我们通过上篇文章搭建的eureka_server(服务中心),eureka_provider(服务提供者)来做测试用例,这里我重新定义eureka_consumer_ribbon模块做为消费服务;先创建service层类和代码: 1 @Service 2 public class UserService implements UserInterface { 3 4 @Autowired 5 protected RestTemplate restTemplate; 6 7 @Override 8 public MoRp<List<MoUser>> getUsers(MoRq rq) { 9 return null; 10 } 11 12 @Override 13 public String getMsg() { 14 15 String str = restTemplate.getForObject("http://EUREKA-PROVIDER/msg", String.class); 16 return str; 17 } 18 } 主要用到了RestTemplate的restTemplate.getForObject函数,然后需要定义个Controller来吧获取到的数据响应到页面上,为了简单这里仅仅只拿getMsg服务接口测试: 1 @RestController 2 public class UserController { 3 4 @Autowired 5 private UserService userService; 6 7 @GetMapping("/msg") 8 public String getMsg(){ 9 10 return userService.getMsg(); 11 } 12 } 最后我们在启动类添加入下代码,注意@LoadBalanced标记必须加,因为咋们引入的eureka依赖里面包含了ribbon(Dalston.RELEASE版本),ribbon封装了负载均衡的算法,如果不加这个注解,那后面rest方法的url就必须是可用的url路径了,当然这里加了注解就可以使用上面说的serviceId: 1 @SpringBootApplication 2 @EnableDiscoveryClient //消费客户端 3 public class EurekaConsumerRibbonApplication { 4 5 @Bean 6 @LoadBalanced //负载均衡 7 RestTemplate restTemplate(){ 8 return new RestTemplate(); 9 } 10 11 public static void main(String[] args) { 12 SpringApplication.run(EurekaConsumerRibbonApplication.class, args); 13 } 14 } 下面来消费方显示的效果: Rest+轮询自定义简易消费组件 自定义消费组件原来和面手工图差不多,就是先想法获取服务提供端真实的接口地址,然后通过rest去调用这个url,得到相应的结果输出;这里自定义了一个ShenniuBanlance的组件类: 1 /** 2 * Created by shenniu on 2018/6 3 * <p> 4 * rest+eureka+自定义client端 5 */ 6 @Component 7 public class ShenniuBanlance { 8 9 @Autowired 10 private RestTemplate restTemplate; 11 12 @Autowired 13 private DiscoveryClient discoveryClient; 14 15 /** 16 * 服务真实地址 ConcurrentHashMap<"服务应用名称", ("真实接口ip", 被访问次数)> 17 */ 18 public static ConcurrentHashMap<String, List<MoService>> sericesMap = new ConcurrentHashMap<>(); 19 20 /** 21 * 设置服务提供者信息到map 22 */ 23 public void setServicesMap() { 24 //获取所有服务提供者applicationName 25 List<String> appNames = discoveryClient.getServices(); 26 27 //存储真实地址到map 28 for (String appName : 29 appNames) { 30 //获取某个服务提供者信息 31 List<ServiceInstance> instanceInfos = discoveryClient.getInstances(appName); 32 if (instanceInfos.isEmpty()) { 33 continue; 34 } 35 36 List<MoService> services = new ArrayList<>(); 37 instanceInfos.forEach(b -> { 38 MoService service = new MoService(); 39 //被访问次数 40 service.setWatch(0L); 41 //真实接口地址 42 service.setUrl(b.getUri().toString()); 43 services.add(service); 44 }); 45 46 //如果存在就更新 47 sericesMap.put(appName.toLowerCase(), services); 48 } 49 } 50 51 /** 52 * 根据app获取轮询方式选中后的service 53 * 54 * @param appName 55 * @return 56 */ 57 public MoService choiceServiceByAppName(String appName) throws Exception { 58 appName = appName.toLowerCase(); 59 //某种app的服务service集合 60 List<MoService> serviceMap = sericesMap.get(appName); 61 if (serviceMap == null) { 62 //初始化所有app服务 63 setServicesMap(); 64 serviceMap = sericesMap.get(appName); 65 if (serviceMap == null) { 66 throw new Exception("未能找到" + appName + "相关服务"); 67 } 68 } 69 70 //筛选出被访问量最小的service 轮询的方式 71 MoService moService = serviceMap.stream().min( 72 Comparator.comparing(MoService::getWatch) 73 ).get(); 74 75 //负载记录+1 76 moService.setWatch(moService.getWatch() + 1); 77 return moService; 78 } 79 80 /** 81 * 自动刷新 服务提供者信息到map 82 */ 83 @Scheduled(fixedDelay = 1000 * 10) 84 public void refreshServicesMap() { 85 setServicesMap(); 86 } 87 88 /** 89 * get请求服务获取返回数据 90 * 91 * @param appName 应用名称 ApplicationName 92 * @param serviceName 服务名称 ServiceName 93 * @param map url上请求参数 94 * @param tClass 返回类型 95 * @param <T> 96 * @return 97 */ 98 public <T> T getServiceData( 99 String appName, String serviceName, 100 Map<String, ?> map, 101 Class<T> tClass) { 102 T result = null; 103 try { 104 //筛选获取真实Service 105 MoService service = choiceServiceByAppName(appName); 106 107 //请求该service的url 108 String apiUrl = service.getUrl() + "/" + serviceName; 109 System.out.println(apiUrl); 110 result = map != null ? 111 restTemplate.getForObject(apiUrl, tClass, map) : 112 restTemplate.getForObject(apiUrl, tClass); 113 } catch (Exception ex) { 114 ex.printStackTrace(); 115 } 116 return result; 117 } 118 119 /** 120 * Service信息 121 */ 122 public class MoService { 123 /** 124 * 负载次数记录数 125 */ 126 private Long watch; 127 /** 128 * 真实接口地址: http://xxx.com/api/add 129 */ 130 private String url; 131 132 public Long getWatch() { 133 return watch; 134 } 135 136 public void setWatch(Long watch) { 137 this.watch = watch; 138 } 139 140 public String getUrl() { 141 return url; 142 } 143 144 public void setUrl(String url) { 145 this.url = url; 146 } 147 } 148 } 以上就是主要的实现代码,代码逻辑:设置服务提供者信息到map-》根据app获取轮询方式选中后的service-》请求服务获取返回数据;轮询实现的原理是使用了一个负载记录数,每次被请求后自动+1,当要获取某个服务提供者时,通过记录数筛选出最小值的一个实例,里面存储有真实接口地址url;调用只需要这样(当然可以弄成注解来调用): 1 @Override 2 public String getMsg() { 3 4 String str = banlance.getServiceData( 5 "EUREKA-PROVIDER", "msg", 6 null, 7 String.class 8 ); 9 return str; 10 } 这里需要注意由于我们在前面RestTemplate使用加入了注解@LoadBalanced,这样使得rest请求时必须用非ip的访问方式(也就是必须serviceid)才能正常响应,不然会提示错误如: 简单来说就是不用再使用ip了,因为有负载均衡机制;当我们去掉这个注解后,我们自定义的组件就能运行成功,效果图和实例1一样就不贴图了; 使用Scheduled刷新服务提供者信息 在微服务架构中,如果某台服务挂了之后,必须要及时更新client端的服务缓存信息,不然就可能请求到down的url去,基于这种考虑我这里采用了EnableSched标记来做定时刷新;首先在启动类增加@EnableScheduling,然后定义一个刷行服务信息的服务如: 1 /** 2 * 自动刷新 服务提供者信息到map 3 */ 4 @Scheduled(fixedDelay = 1000 * 10) 5 public void refreshServicesMap() { 6 setServicesMap(); 7 } 为了方便看测试效果,我们在server,provider(2个),consumer已经启动的情况下,再启动一个端口为2005的provider服务;然后刷新consumer接口看下效果: 这个时候能够看到调用2005端口的接口成功了,通过@Scheduled定时服务吧最新或者失效的服务加入|移除掉,就达到了咋们的需求了;如果你觉得该篇内容对你有帮助,不防赞一下,谢谢。 git地址: https://github.com/shenniubuxing3nuget发布包: https://www.nuget.org/profiles/shenniubuxing3

优秀的个人博客,低调大师

springCloud(13):使用Zuul构建微服务网关-简介

一、为什么要使用微服务网关 不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求。如:一个电影购票的手机APP,可能会调用多个微服务,才能完成一次购票的业务流程。如果让客户端直接与各个微服务通信,会有以下的问题: 1、客户端会多次请求不同的微服务,增加了客户端的复杂性; 2、存在跨域请求,在一定场景下处理相对复杂; 3、认证复杂,每个服务都需要独立认证; 4、难以重构,随着项目的迭代,可能需要重新划分微服务,如果客户端直接与微服务通信,那么重构将会很难实施; 5、某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问会有一定的困难。 以上问题可借助微服务网关解决,微服务网关是介于客户端和服务端之间的中间层,所有的外部请求都会先经过微服务网关,然后由微服务网关请求各个微服务。 微服务网关封装了应用程序的内部结构,客户端只须跟网关交互,而无须直接调用特定微服务的接口,这样,开发就可以得到简化。不仅如此,使用微服务网关还有以下优点: 1、易于监控。可在微服务网关收集监控数据并将其推送到外部系统进行分析; 2、易于认证。可在微服务网关上进行认证,然后再将请求转发到后端的微服务,而无须再每个微服务中进行认证; 3、减少了客户端与各个微服务之间的交互次数。 二、Zuul简介 Zuul是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用。 Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能: 1、身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求; 2、审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图; 3、动态路由:动态地将请求路由到不同的后端集群; 4、压力测试:逐渐增加指向集群的流量,以了解性能; 5、负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求; 6、静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群; 7、多区域弹性:跨域AWS Region进行请求路由。 Spring Cloud对Zuul进行了整合与增强。目前,Zuul使用的默认HTTP客户端是Apache HTTP Client。 三、编写一个Zuul微服务网关 1、添加依赖 1 2 3 4 5 <!--zuul--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> 2、在启动类上添加@EnableZuulProxy注解,声明一个Zuul代理,改代理使用Ribbon来定位注册在EurekaServer中的微服务;同时,改代理还整合了hystrix,所有经过Zuul的请求都会在Hystrix命令中执行。 3、编写application.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 spring: profiles: active: -dev application: name:microservice-gateway-zuul eureka: client: service-url: defaultZone:http://liuy2:5010/eureka/ #设置与EurekaServer交互的地址,查询服务和注册服务都需要依赖这个地址,多个用逗号分隔 instance: prefer-ip-address:true --- spring: profiles: active:dev server: port:5016 这样,一个简单的微服务网关就编写完成了。这里仅是添加了Zuul的依赖,并将Zuul注册到Eureka Server上。 四、测试 4.1、测试路由规则 1、依次启动eureka-server(4010)、provide-user(4011)、hystrix-consumer-movie(5012)、microservice-gateway-zuul(5016) 2、访问http://localhost:5016/hystrix-consumer-movie/user/1,请求会被转发到http://localhost:5012/user/1 3、访问http://localhost:5016/provide-user/1,请求会被转发到http://localhost:4011/1 总结: 说明默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/**会被转发到serviceId对应的微服务。 4.2、测试Hystrix容错与监控 1、依次启动eureka-server(4010)、provide-user(4011)、hystrix-consumer-movie(5012)、microservice-gateway-zuul(5016)、hystrix-dashboard(5013) 2、访问http://localhost:5016/hystrix-consumer-movie/user/1,可以获取正常用户数据 3、关闭provide-user微服务,再访问http://localhost:5016/hystrix-consumer-movie/user/1 4、访问http://localhost:5013/hystrix.stream进入Hystrix Dashboard页面,在URL栏输入http://localhost:5016/hystrix.stream,随意指定一个title,点击monitor Stream按钮。 总结:说明Zuul已经整合了Hystrix。 本文转自我爱大金子博客51CTO博客,原文链接http://blog.51cto.com/1754966750/1958373如需转载请自行联系原作者 我爱大金子

优秀的个人博客,低调大师

Jboot v3.10.7 发布,基于 JFinal 类似 SpringCloud 的框架

Jboot 一个更简单的分布式、微服务框架。 Jboot是一个基于 JFinal、JFinal-Undertow、Dubbo、Seata、Sentinel、ShardingSphere、Nacos 等开发的微服务框架,帮助开发者降低微服务、分布式开发门槛。爽爽开发,快乐生活。 到目前为止,Jboot 已经开源超过了 5 年的时间,迭代了 200+ 个版本,已经被超过 1000+ 公司在使用,其中包含了多个知名的上市公司,我们了解到的多个使用 Jboot 开发的产品,用户量超过 1亿 以上。 Jboot v3.10.7 更新内容如下: 新增:JbootHttpRequest 添加 sslContext 的配置,方便自定义 ssl 新增:JbootConfigManager 添加 setBootProperties 方法,方便用于添加启动配置 新增:工具类 ReflectUtil 新增 searchFieldList() 方法 新增:添加 TypeConverterFunc,用于处理前端传入枚举内容 优化:JbootShiroInvokeListener,在 onInvokeBefore() 方法添加返回值 AuthorizeResult,更加方便整合 Jwt sso 等 优化:升级 jedis/jsoup/jfinal/fastjson 等到最新版本 修复:ClassScanner 添加排除的前缀时,如果有大写字母不生效的问题 修复:当使用 @Api(collect={}) 时,子 Controller 路径错误的问题 Jboot 开发文档: http://www.jboot.io 同时,Jboot 官方也推出了收费的、企业级快速开发框架 JbootAdmin (如下图所示),真诚的为各位开发者提供一站式、保姆式服务。请咨询海哥。 更多关于 JbootAdmin 请参考:http://jboot.io/jbootadmin/feature.html Maven 依赖: <dependency> <groupId>io.jboot</groupId> <artifactId>jboot</artifactId> <version>3.10.7</version> </dependency> Hello World: @RequestMapping("/") public class HelloWorld extends JbootController { public void index(){ renderText("hello world"); } public static void main(String[] args){ JbootApplication.run(args); } }

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册