首页>>后端>>SpringBoot->springcloud调用流程(springcloud服务调用原理)

springcloud调用流程(springcloud服务调用原理)

时间:2023-12-01 本站 点击:0

SpringCloud入门搭建及服务调用

开发工具:idea 2020.2.3

java:1.8

maven:3.3.9

SpringBoot:2.1.3.RELEASE

SpringCloud:Greenwich.SR5 (版本和SpringBoot必须对应,对应表自行百度)

idea配置我就不细说了

然后next

finish

然后配置pom.xml:

一般在父项目配置

然后配置依赖,这里只是一个springboot项目,所以配一个springboot就行了:

然后配置pom.xml,它们俩都是独立的springboot项目了,这里也可以和父类工程做依赖继承,但是这里就没必要,更凸显服务的独立性:

controller:

power启动类:

UserController.java

在这里调用另一个服务power服务的接口,可以使用reatTeplate来实现,需要配置

reaTeplate配置文件:AppConfig.java

user服务启动类:

user服务的 application.yml

同样可以以相同方式在power服务中调用user的接口

然后在浏览器:

127.0.0.1:6060/power/getPower.do(6060是power服务的端口)

127.0.0.1:7070/user/getUser.do调用自己的接口(7070是user服务的端口)

127.0.0.1:7070/user/getPower.do调用power的接口

至此实现了不同服务之间的调用

spring cloud服务之间怎么调用

比如有一个服务如下

@EnableEurekaClient

@SpringBootApplication

@RestController

public class EurekaClientApplication {

   @Value("${server.port}")

   String port;

   @RequestMapping("/hi")

   public String home(@RequestParam String name) {

      return "hi "+name+",i am from port:" +port;

   }

   public static void main(String[] args) {

      SpringApplication.run(EurekaClientApplication.class, args);

   }

}

这个服务名为:EurekaClient

----------------------------------------------------------------------------------------------

调用采用以下方式:

定义一个借口,注解@FeignClient(value = "EUREKACLIENT")

@Service

@FeignClient(value = "EUREKACLIENT")//服务名

public interface SchedualServiceHi {

    @RequestMapping(value = "/hi",method = RequestMethod.GET)

    String sayHiFromClientOne(@RequestParam(value = "name") String name);

}

@RestController

public class HiController {

    @Autowired

    SchedualServiceHi schedualServiceHi;

    @RequestMapping(value = "/hi",method = RequestMethod.GET)

    public String sayHi(@RequestParam String name){

        return schedualServiceHi.sayHiFromClientOne(name);

    }

}

springcloud执行流程

1.Servlet

zuul.servletPath默认配置为/zuul,故请求为/zuul开头的会跳过dispatcherServlet直接进入ZuulServlet,该配置可以自定义配置,例如用于大文件上传

2.ZuulServlet中service方法

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

try {

this.init((HttpServletRequest)servletRequest, (HttpServletResponse)servletResponse);

RequestContext context = RequestContext.getCurrentContext();

context.setZuulEngineRan();

try {

//运行pre过滤器

this.preRoute();

} catch (ZuulException var12) {

//有异常,执行errorFilter

this.error(var12);

//再执行postFilter

this.postRoute();

return;

}

try {

//运行rote过滤器

this.route();

} catch (ZuulException var13) {

//有异常,执行errorFilter

this.error(var13);

//再执行postFilter

this.postRoute();

return;

}

try {

//运行post过滤器

this.postRoute();

} catch (ZuulException var11) {

//有异常,执行errorFilter

this.error(var11);

}

} catch (Throwable var14) {

this.error(new ZuulException(var14, 500, "UNHANDLED_EXCEPTION_" + var14.getClass().getName()));

} finally {

RequestContext.getCurrentContext().unset();

}

}

3.FilterProcessor

其运行交由FilterProcessor中的方法runFilters,根据service中的顺序,取不同的filter类型,执行其中的run方法

public Object runFilters(String sType) throws Throwable {

if (RequestContext.getCurrentContext().debugRouting()) {

Debug.addRoutingDebug("Invoking {" + sType + "} type filters");

}

boolean bResult = false;

ListZuulFilter list = FilterLoader.getInstance().getFiltersByType(sType);

if (list != null) {

for(int i = 0; i list.size(); ++i) {

ZuulFilter zuulFilter = (ZuulFilter)list.get(i);

Object result = this.processZuulFilter(zuulFilter);//见下面zuulFilter的runFilter()

if (result != null result instanceof Boolean) {

bResult |= ((Boolean)result).booleanValue();

}

}

}

return bResult;

}

zuulFilter的runFilter方法,当filter的shouldFilter()返回true时才执行run()方法

public ZuulFilterResult runFilter() {

ZuulFilterResult zr = new ZuulFilterResult();

if (!this.isFilterDisabled()) {

if (this.shouldFilter()) {

Tracer t = TracerFactory.instance().startMicroTracer("ZUUL::" + this.getClass().getSimpleName());

try {

Object res = this.run();

zr = new ZuulFilterResult(res, ExecutionStatus.SUCCESS);

} catch (Throwable var7) {

t.setName("ZUUL::" + this.getClass().getSimpleName() + " failed");

zr = new ZuulFilterResult(ExecutionStatus.FAILED);

zr.setException(var7);

} finally {

t.stopAndLog();

}

} else {

zr = new ZuulFilterResult(ExecutionStatus.SKIPPED);

}

}

return zr;

}

4.获取过滤器FilterRegistry

其中的属性private final ConcurrentHashMapString, ZuulFilter filters = new ConcurrentHashMap();

保存所有的过滤器

例子中有12个(其中有两个为自定义的):

[org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter@3dc68586,

org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter@4001d8c1,

org.springframework.cl

SpringCloud远程调用-OpenFeign

OpenFeign是SpringCloud提供的一个声明式客户端组件,可以通过注解和接口的组合实现服务的远程接口调用,并且与Eureka和Ribbon组合使用能够实现负载均衡的效果

1.在pom.xml中引入依赖

2.在主启动类上添加 @EnableFeignClients 注解,开启Feign支持

3.创建feignClient接口,并添加注解(指定需要调用的服务和接口)

4.在Controller中注入后,发起远程调用

测试:访问

OpenFeign远程调用的默认等待时长为1秒,超时后报错

1.在消费者服务的application.yml文件中设置超时时间

2.在服务提供者端的接口处设置睡眠时间

3.在服务消费者端打印时间

重启后访问: ,发现等待一段时间后,页面获取到端口值,访问成功,说明时间控制生效

控制台打印信息如下:

OpenFeign提供了日志打印功能,能够对feign借口的调用情况进行监控和输出

Fegin的日志级别:

2.在yml中指定显示哪一个接口的信息

访问接口,可以看到请求你的详细信息

Spring Cloud调用接口过程

Feign -----Hystrix —Ribbon —Http Client(apache http components 或者 Okhttp) 具体交互流程上

Hystrix 是一个供分布式系统使用,提供 延迟 和 容错 功能,保证复杂的分布系统在面临不可避免的失败时,仍能有其弹性。

比如系统中有很多服务,当某些服务不稳定的时候,使用这些服务的用户线程将会阻塞,如果没有隔离机制,系统随时就有可能会挂掉,从而带来很大的风险。SpringCloud使用 Hystrix组件提供断路器、资源隔离与自我修复功能 。下图表示服务B触发了断路器,阻止了级联失败

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,提高分布式系统的弹性

熔断机制是应对雪崩效应的一种微服务链路保户机制,当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的相应信息。当检测当该节点微服务调用响应正常后恢复调用链路,熔断机制的注解是@HystrixCommand

“熔断器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控,,某个异常条件被触发,直接熔断整个服务。,向调用方法返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出吊牌用方法无法处理的异常,就保证了服务调用方的线程不会被长时间占用,避免故障在分布式系统中蔓延,乃至雪崩。

服务降级处理是在客户端实现完成的,与服务端没有关系

整体资源快不够了,忍痛将某些服务单元先关掉,关闭后还要返回一些可处理的备选方法,待渡过难关,再开启回来。

分布式项目中,有数十个依赖关系,每个依赖关系在某些时候不可避免地失败,

服务雪崩 :当A调用微服务B,B调C,和其他微服务,这是扇出,当扇出链路上某个微服务调用响应时间过长或者不可用,对微服务的A的调用就会占用越来越多的系统资源,导致系统崩溃,所谓的雪崩效应

服务熔断 :一般是某个服务异常引起的,相当于“保险丝”,当某个异常条件被触发,直接熔断整个服务,不是等到此服务超时

服务降级 :降级一般是从整体负荷考虑,当某个服务熔断之后,服务器将不再被调用,客户端可自己准备一个本地的fallback回调,返回一个缺省值,虽然服务水平下降,当能用,比直接挂掉要强

springcloud是spring,采用AOP的思想,异常处理信息,我们某个服务的功能是每个方法,我们还可以使用AOP直接在api层通过接口设置服务降级。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/SpringBoot/6088.html