文章目录
- 介绍
- 技术
- 接口数据流向
- 数据表
- 新建项目
- Eurak(发现)
- Eureka的作用
- 架构
- Eurak Server代码
- Eureka客户端代码
- 利用Feign实现服务间调用
- 介绍
- 代码
- 利用Ribbon实现负载均衡
- 利用Hystrix实现断路器
- 整合两个服务
- 通过网关Zuul实现路由功能
- 两个特点
- Zuul集成
- 实现网关过滤器
介绍
技术
之前有用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请求
代码
价格中调用课程服务
引入依赖
代码语言:javascript复制<!-- openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置文件
代码语言:javascript复制#openfeign消费的负载均衡后期再配
加注解
代码语言:javascript复制//启动类的客户端
@EnableFeignClients
客户端(在调用类写接口,复制被调用服务的controller方法)
代码语言:javascript复制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实现负载均衡
修改配置文件
代码语言:javascript复制price服务调用course服务的负载均衡设置
#openfeign消费的负载均衡
course-list.ribbon.NFLoadBanlancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
利用Hystrix实现断路器
比如获取用户信息卡住,但数据库的连接池一直未被释放。系统崩溃 断路器保护,某一处出现问题,保证不影响全部不可用,避免故障蔓延
依赖pom
代码语言:javascript复制<!-- 断路器 客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
配置
代码语言:javascript复制#断路器 客户端(默认关闭)
feign.hystrix.enabled=true
启动类注解
代码语言:javascript复制@EnableCircuitBreaker
断路器实现类CourseListClientHystrix
代码语言:javascript复制package com.bennyrhys.course.client;
import com.bennyrhys.entity.Course;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
/**
* 描述: 断路器实现类
*/
@Component
public 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;
}
}
指明调用服务的断路器类
代码语言:javascript复制/**
* @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
代码语言:javascript复制 Integer id;
Integer courseId;
String name;
Integer price;
service
代码语言:javascript复制 @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
引入依赖
代码语言:javascript复制<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>
配置文件
代码语言:javascript复制spring.application.name=course-gateway
server.port=9000
logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}
mybatis.configuration.map-underscore-to-camel-case=true
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
#zuul.prefix=/bennyrhys
zuul.routes.course-list.path=/list/**
zuul.routes.course-list.service-id=course-list
zuul.routes.course-price.path=/price/**
zuul.routes.course-price.service-id=course-price
启动类 注解
代码语言:javascript复制package com.bennyrhys.course;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
* 描述: 网关启动类
*/
@EnableZuulProxy
@SpringCloudApplication
public class ZuulGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
}
效果图
实现网关过滤器
过滤前
代码语言:javascript复制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;
/**
* 描述: 记录请求时间
*/
@Component
public 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;
}
}
过滤后
代码语言:javascript复制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;
/**
* 描述: 请求处理后的过滤器
*/
@Component
public 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