9

【SpringCloud】SpringCloud开发课程查询功能

 3 years ago
source link: https://blog.csdn.net/weixin_43469680/article/details/111593251
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在这里插入图片描述
在这里插入图片描述之前有用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实现断路器

比如获取用户信息卡住,但数据库的连接池一直未被释放。系统崩溃
断路器保护,某一处出现问题,保证不影响全部不可用,避免故障蔓延

在这里插入图片描述
依赖pom

<!--        断路器 客户端-->
        <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;

/**
 * 描述:     断路器实现类
 */
@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;
    }
}

指明调用服务的断路器类

/**
 * @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-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([%15.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

启动类 注解

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);
    }
}

效果图
在这里插入图片描述

实现网关过滤器

在这里插入图片描述过滤前

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;
    }
}
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


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK