SpringCloud开发课程查询功能
作者:瑞 新 发布时间:2022-04-21 14:22:46
介绍
技术
之前有用eureka 现在用nacos
工作流和gateway
接口数据流向
数据表
新建项目
新建cloud-删除src-新建modle
Eurak(发现)
Eureka的作用
114、物业 (注册中心、心跳机制60s失效踢除)
没有服务注册于发现可以,但是会引来无穷无尽的麻烦
静态ip变更,影响多服务模块
架构
Eurak Server代码
新建moudle,和业务完全独立
pom依赖,最外层pomcloud版本号
新建配置文件
注解启动
验证http://localhost:8000/
Eureka客户端代码
配置dom
配置properties
启动client
利用Feign实现服务间调用
介绍
历史
netflex -> open (捐给spring cloud)
非常方便
基于接口和注解,和本地方法一样爽的http请求
代码
价格中调用课程服务
引入依赖
<!-- openfeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
配置文件
#openfeign消费的负载均衡后期再配
加注解
//启动类的客户端@EnableFeignClients
客户端(在调用类写接口,复制被调用服务的controller方法)
package com.bennyrhys.course.client;import com.bennyrhys.entity.Course;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import java.util.List;/** * @Author bennyrhys * @Date 12/27/20 8:04 PM * 课程列表的Feign客户端 */@FeignClient("course-list")public interface CourseListClient { @GetMapping("/course") List<Course> getList();}
验证pom中(自动引入其他服务的依赖)
controller(在price服务中调用course服务的方法)
验证
利用Ribbon实现负载均衡
修改配置文件
price服务调用course服务的负载均衡设置
#openfeign消费的负载均衡course-list.ribbon.NFLoadBanlancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
利用Hystrix实现断路器
比如获取用户信息卡住,但数据库的连接池一直未被释放。系统崩溃
断路器保护,某一处出现问题,保证不影响全部不可用,避免故障蔓延
<!-- 断路器 客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
配置
#断路器 客户端(默认关闭)feign.hystrix.enabled=true
启动类注解
@EnableCircuitBreaker
断路器实现类CourseListClientHystrix
package com.bennyrhys.course.client;import com.bennyrhys.entity.Course;import java.util.ArrayList;import java.util.List;import org.springframework.stereotype.Component;/** * 描述: 断路器实现类 */@Componentpublic class CourseListClientHystrix implements CourseListClient{ @Override public List<Course> getList() { List<Course> defaultCourses = new ArrayList<>(); Course course = new Course(); course.setId(1); course.setCourseId(1); course.setCourseName("默认课程"); course.setValid(1); defaultCourses.add(course); return defaultCourses; }}
指明调用服务的断路器类
/** * @Author bennyrhys * @Date 12/27/20 8:04 PM * 课程列表的Feign客户端 */@FeignClient(value = "course-list", fallback = CourseListClientHystrix.class)@Primary //防止调用服务的controller爆红线不好看public interface CourseListClient { @GetMapping("/course") List<Course> getList();}
断路器效果
整合两个服务
将课程列表和课程价格进行整合
返回实体CourseAndPrice
Integer id; Integer courseId; String name; Integer price;
service
@Override public List<CourseAndPrice> getCoursesAndPrice() { List<CourseAndPrice> courseAndPriceList = new ArrayList<>(); List<Course> courses = courseListClient.courseList(); for (int i = 0; i < courses.size(); i++) { Course course = courses.get(i); if (course != null) { CoursePrice coursePrice = getCoursePrice(course.getCourseId()); CourseAndPrice courseAndPrice = new CourseAndPrice(); courseAndPrice.setPrice(coursePrice.getPrice()); courseAndPrice.setName(course.getCourseName()); courseAndPrice.setId(course.getId()); courseAndPrice.setCourseId(course.getCourseId()); courseAndPriceList.add(courseAndPrice); } } return courseAndPriceList; }}
通过网关Zuul实现路由功能
两个特点
Zuul集成
新建mudle模块sourse-zuul
引入依赖
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
配置文件
spring.application.name=course-gatewayserver.port=9000logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}mybatis.configuration.map-underscore-to-camel-case=trueeureka.client.service-url.defaultZone=http://localhost:8000/eureka/#zuul.prefix=/bennyrhyszuul.routes.course-list.path=/list/**zuul.routes.course-list.service-id=course-listzuul.routes.course-price.path=/price/**zuul.routes.course-price.service-id=course-price
启动类 注解
package com.bennyrhys.course;import org.springframework.boot.SpringApplication;import org.springframework.cloud.client.SpringCloudApplication;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;/** * 描述: 网关启动类 */@EnableZuulProxy@SpringCloudApplicationpublic class ZuulGatewayApplication { public static void main(String[] args) { SpringApplication.run(ZuulGatewayApplication.class, args); }}
效果图
实现网关过滤器
过滤前
package com.bennyrhys.course.filter;import com.netflix.zuul.ZuulFilter;import com.netflix.zuul.context.RequestContext;import com.netflix.zuul.exception.ZuulException;import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;import org.springframework.stereotype.Component;/** * 描述: 记录请求时间 */@Componentpublic class PreRequestFilter extends ZuulFilter { @Override public String filterType() { //过滤器的类型 return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { //是否启用过滤器 return true; } @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); currentContext.set("startTime", System.currentTimeMillis()); System.out.println("过滤器已经记录时间"); return null; }}
过滤后
package com.bennyrhys.course.filter;import com.netflix.zuul.ZuulFilter;import com.netflix.zuul.context.RequestContext;import com.netflix.zuul.exception.ZuulException;import org.springframework.cache.annotation.Cacheable;import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;import org.springframework.stereotype.Component;/** * 描述: 请求处理后的过滤器 */@Componentpublic class PostRequestFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.POST_TYPE; } @Override public int filterOrder() { return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); Long startTime = (Long) currentContext.get("startTime"); long duration = System.currentTimeMillis() - startTime; String requestURI = currentContext.getRequest().getRequestURI(); System.out.println("uri:" + requestURI + ",处理时长:" + duration); return null; }}
uri:/bennyrhys/list/course,处理时长:919
来源:https://blog.csdn.net/weixin_43469680/article/details/111593251
猜你喜欢
- 1.背景Java语言相比于C和C++,一个最大的特点就是不需要程序员自己手动去申请和释放内存,这一切交由JVM来完成。在Java中,运行时的
- 简介optional类是java8中引入的针对NPE问题的一种优美处理方式,源码作者也希望以此替代null。历史1965年,英国一位名为To
- 具体代码如下所示:***web.xml***<?xml version="1.0" encoding="
- 光流的概念是由一个叫Gibson的哥们在1950年提出来的。它描述是空间运动物体在观察成像平面上的像素运动的瞬时速度,利用图像序列中像素在时
- 今天有个项目需要使用redis,并且有使用脚本的需求。但是因为之前没有写过,所以还有一点点不熟悉,今天记录一下。原因:原子操作,redis会
- 命令模式的介绍命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象每一个命令都是一个操作:请求的一方发出
- 我object != null要避免很多NullPointerException。有什么替代方法:if (someobject != nul
- 理论上Object类是所有类的父类,即直接或间接的继承java.lang.Object类。由于所有的类都继承在Object类,因此省略了ex
- Android Studio 在引用外部依赖时,发现一直无法引用外部依赖。刚开始以为是墙的问题,尝试修改Gradle配置,未解决问题。最终发
- 在项目里,我需要做一个Spring Boot结合Thymeleaf前端模版,结合JPA实现分页的演示效果。做的时候发现有些问题,也查了现有网
- 操作符就是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observa
- 初始化方式一:@PostConstruct注解假设类UserController有个成员变量UserService被@Autowired修饰
- 本文实例为大家分享了java实现小球碰撞的具体代码,供大家参考,具体内容如下这次我们做一个小球的碰撞的游戏,规则是:按下添加按钮,窗口的中心
- 当数据库中数据条数过多时,一个页面就不能显示,这是要设置分页查询,首先要使用的是数据库sql语句的limit条件实现分组查询sql语句大概形
- 本文介绍了Spring Security 控制授权的方法,分享给大家,具体如下:使用授权方法进行授权配置每一个 Spring Securit
- 上篇文章老王买产品 我们从最原始的基本实现方法,到简单(静态)工厂,然后使用工厂方法设计模式进行改造,最后考虑产品会产生变体,我们
- 大致分为以下几个方面:一些查询指令整理使用SQL语句进行特殊查询检测表字段是否存在数据库升级数据库表字段赋初始值一、查询指令整理1.链式执行
- 在本文中,我们将介绍一个非常有用的Spring功能,该功能允许我们基于一个或多个Spring注释创建自己的注释。假设我们有一组经常一起使用的
- 用的Idea,在写MyBatis时,测试发现有以下的报错信息Error parsing SQL Mapper Configuration.
- 1. 什么是λ表达式λ表达式本质上是一个匿名方法。让我们来看下面这个例子: public int add(int x, int