SpringCloud分布式框架

Springcloud分布式框架

 

SpringCloud概述

SpringCloud也是基于RPC远程调用的,是在SOA架构基础上演变而来,相对于SOA架构来说更加请假,而且开发要求不是特别严格,基于HTTP+REST+JSON进行数据的传输

SpringCloud基于SpringBoot,提供很多组件,有EurekaRibbonFegionzuulconfig

 

二、Eureka注册中心

SpringCloud当中自带注册中心,该角色就是Eureka,主要用于服务发现和调用,分为两个角色:

EurekaServer:服务端    @EnableEurekaServer

管理服务,对外暴露地址

 

EurekaClient:客户端    @EnableEurekaClient

连接到服务端,例如生产者连接到服务端,向上注册服务。   消费者连接到服务端,往下取服务

 

 

1注册中心环境搭建

步骤一:导入依赖

父工程中导入SpringBoot依赖

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.1.4.RELEASE</version>

</parent>

子工程:

<dependencies>

 

<!--eureka依赖-->

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

</dependency>

 

</dependencies>

 

<dependencyManagement>

<dependencies>

  <!--springCloud依赖-->

  <dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Greenwich.RELEASE</version>

<type>pom</type>

<scope>import</scope>

  </dependency>

</dependencies>

</dependencyManagement>

 

2步骤二:创建配置文件,配置eureka

#声明端口

server:

  port: 8001

#配置eureka

eureka:

  client:

#是否把自己注册到注册中心当中去,默认值为true

register-with-eureka: false

#表示是否从Eureka Server获取注册信息,默认为true

fetch-registry: false

#配置注册中心地址

service-url:

  defaultZone: http://localhost:8001/eureka

#应用名称,应用名不能有_

spring:

  application:

name: eureka-server

 

3步骤三:创建启动类

@SpringBootApplication

@EnableEurekaServer     //代表是Eureka服务器

public class StartEurekaServer {

public static void main(String[] args) {

SpringApplication.run(StartEurekaServer.class,args);

}

}

4Eureka生产者

步骤一:创建一个业务接口

/**

 * 业务接口

 */

public interface DoSomeService {

/**

 * 业务方法

 * @return

 */

public String doSome();

}

步骤二:创建一个业务接口的实现类,利用HTTP方式将次接口暴露出去

/**

 * 业务接口的实现类

 */

@RestController

public class DoSomeServiceImpl implements DoSomeService {

@RequestMapping("/doSome")

@Override

public String doSome() {

System.out.println("DoSomeService 业务接口的doSome方法");

return "Eureka Provider";

}

}

步骤三:创建配置文件,指定端口,应用名称,Eureka注册中心

#端口号

server:

  port: 9001

#应用名称

spring:

  application:

name: eureka-provider

#配置EurekaServer注册中心地址

eureka:

  client:

service-url:

  defaultZone: http://localhost:8001/eureka

 

 

 

5Eureka消费者

步骤一:创建一个控制器,用于通过HTTP请求到服务提供者

@RestController

@RequestMapping("/doSomeCon")

public class DoSomeController {

@Resource

private RestTemplate restTemplate;

 

@RequestMapping("/doSome")

public String doSome(){

System.out.println("服务消费者,控制方法");

String returnValue = restTemplate.getForObject("http://localhost:9001/doSome", String.class);

return returnValue;

}

}

步骤二:创建一个启动类,要将RestTemplate模板注入到容器当中

@SpringBootApplication

@EnableEurekaClient

public class StartConsumer {

public static void main(String[] args) {

SpringApplication.run(StartConsumer.class,args);

}

 

 

//注入RestTemplate模板

@Bean

RestTemplate restTemplate(){

return new RestTemplate();

}

}

步骤三:创建配置文件,指定端口,应用名称,Eureka注册中心

#端口号

server:

  port: 10001

#应用名称

spring:

  application:

name: eureka-consumer

#注册中心

eureka:

  client:

service-url:

  defaultZone: http://localhost:8001/eureka

 

Ribbon负载均衡

1搭建生产者服务集群

条件:端口号不同,应用名称要相同,数据同步

 

问题:消费者调用怎么办?

消费者不能根据端口号调用,通过应用名字调用

@RequestMapping("/doSome")

public String doSome(){

System.out.println("服务消费者,控制方法");

String returnValue = restTemplate.getForObject("http://eureka-provider/doSome", String.class);

return returnValue;

}

附带问题:restTemplate不知道要使用应用名字调用,默认使用的是IP+端口,解决办法:在注入RestTemplate模板时加入@LoadBalanced注解

//注入RestTemplate模板

@Bean

@LoadBalanced   //负载均衡配置,可以使用应用名称调用服务

RestTemplate restTemplate(){

return new RestTemplate();

}

 

 

2调用的机制(负载均衡机制)

RestTemplate模板上加入@LoadBalanced注解,即可实现Ribbon负载均衡,默认机制为轮训机制

 

调整机制:

自定义算法,也可以使用随机访问

 

 

//重新创建一个均衡策略,表示不使用默认

@Bean

public IRule getIReule(){ //通过获取一个IRule对象,

return  new  RandomRule();  //达到的目的,用我们重新选择的随机,替代默认的轮训方式

}

 

 

四、Fegion服务调用

开发步骤:

1步骤一:在原有基础上导入fegin依赖

<!--Fegin依赖-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

2步骤二:创建调用的服务接口

使用fegin注解指定调用应用,和该应用的哪个地址

/**

 * 会员服务

 */

@FeignClient("member-service")      //指定调用的服务应用名称

public interface MemberService {

//获取会员ID服务方法

@RequestMapping("/getMemberId") //调用方法的地址

public Integer getMemberId();

}

3步骤三:创建配置文件

#端口号

server:

  port: 10001

#应用名称

spring:

  application:

name: order-service

#eureka注册中心地址

eureka:

  client:

service-url:

  defaultZone: http://localhost:8001/eureka

4步骤四:启动类

@SpringBootApplication

@EnableEurekaClient

@EnableFeignClients

public class StartOrderService {

public static void main(String[] args) {

SpringApplication.run(StartOrderService.class,args);

}

}

Fegin默认集成Ribbon,带负载均衡,默认轮训机制

五、zuul路由网关

作用:路由转发和过滤

 

1步骤一:导入依赖

<dependencies>

<!--eureka依赖-->

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

</dependency>

<!--zuul依赖-->

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-netflix-zuul</artifactId>

</dependency>

  </dependencies>

 

  <dependencyManagement>

<dependencies>

  <!--springCloud依赖-->

  <dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Greenwich.RELEASE</version>

<type>pom</type>

<scope>import</scope>

  </dependency>

</dependencies>

  </dependencyManagement>

2步骤二:配置配置文件

#端口

server:

  port: 20001

#应用名称

spring:

  application:

name: zuul

#注入到注册中心

eureka:

  client:

service-url:

  defaultZone: http://localhost:8001/eureka

#zuul路由配置

zuul:

  routes:

api-a:

  path: /member/**             #外界访问地址

  service-id: member-service   #真实服务名称

api-b:

  path: /order/**

  service-id: order-service

3步骤三:启动类

@SpringBootApplication

@EnableEurekaClient

@EnableZuulProxy    //zuul路由网关代理

public class StartZuul {

public static void main(String[] args) {

SpringApplication.run(StartZuul.class,args);

}

}

 

 

 

4zuul过滤器

zuul路由网关工程当中,加入过滤器

实例:需要传递token,如果不传递则不能正常请求

@Component

public class MyFilter extends ZuulFilter {

/**

 * filterType过滤类型

 * @return 代表过滤的时机

 */

@Override

public String filterType() {

return "pre";

}

 

/**

 * 过滤器执行顺序,值越小越先执行

 * @return

 */

@Override

public int filterOrder() {

return 0;

}

 

/**

 * 是否执行run

 * @return

 */

@Override

public boolean shouldFilter() {

return true;

}

 

/**

 * 过滤方法

 * @return

 * @throws ZuulException

 */

@Override

public Object run() throws ZuulException {

RequestContext ctx = RequestContext.getCurrentContext();

HttpServletRequest request = ctx.getRequest();

//获取到token

String token = request.getParameter("token");

if(token!=null){

return null;

}

//没有传递Token

ctx.setSendZuulResponse(false);     //不会转发

ctx.setResponseStatusCode(401);     //401代表没有需要的参数

try {

ctx.getResponse().getWriter().write("token is empty");

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

}

 

 

 

六、断路器Hytrix

服务雪崩产生原因:

1.某几个机器故障

2.服务器负载发生变化

3.人为因素

雪崩解决办法:

1.熔断模式:类似于保险丝,当服务响应时间过长或者请求处理不过来的情况下,我们可以熔断该服务,停止服务的调用,快速释放资源,等服务恢复后恢复正常调用

2.隔离模式

3.限流模式

 

 

1Fegin配置熔断

步骤一:开启熔断,配置调用服务的超时时间

#开启熔断

feign:

    hystrix:

enabled: true

##配置服务处理的时间,超过该时间服务没有相应就执行服务的降级

##配置服务处理的时间,超过该时间服务没有相应就执行服务的降级
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000

2步骤二:开启熔断注解

@SpringBootApplication

@EnableEurekaClient

@EnableFeignClients

@EnableHystrix

public class StartOrderService {

public static void main(String[] args) {

SpringApplication.run(StartOrderService.class,args);

}

//重新创建一个均衡策略,表示不使用默认

@Bean

public IRule getIReule(){ //通过获取一个IRule对象,

return  new RandomRule();  //达到的目的,用我们重新选择的随机,替代默认的轮训方式

}

}

 

3步骤三:服务降级,如果服务在一段时间内没有相应,那么我们执行服务降级处理

在本地新建一个实现类,然后重写业务方法,实现降级处理

@Component

public class MemberServiceImplLocal implements MemberService {

@Override

public Integer getMemberId() {

System.out.println("服务降级处理");

return 20002;

}

}

4步骤四:Fegin调用指定fallback降级处理执行得类

/**

* 会员服务,fallback服务降级执行得类

*/

@FeignClient(name = "member-service",fallback = MemberServiceImplLocal.class)      //指定调用的服务应用名称

public interface MemberService {

//获取会员ID服务方法

@RequestMapping("/getMemberId") //调用方法的地址

public Integer getMemberId();

}

 

 

 

 

七、Rest配置熔断

1、步骤一:降级处理创建处理方法@HystrixCommand注解指定降级处理的方法名称

@RestController

@RequestMapping("/order")

public class OrderController {

/*@Resource

private MemberService memberService;*/

 


@Resource
private RestTemplate restTemplate;


@RequestMapping("/getOrderByMemberId")
@HystrixCommand(fallbackMethod = "lower")       //服务降级执行得方法
public Object getOrderByMemberId(){
    return restTemplate.getForObject("http://member-service/getMemberId",String.class);
}

public Object lower(){
    return "服务降级";
}

 

 

@RequestMapping("/requestOrder")

public Object requestOrder(){

return "order success";

}

}

2步骤二:配置降级处理时间

##配置服务处理的时间,超过该时间服务没有相应就执行服务的降级
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000

3步骤三:在启动类中加入Hystrix注解

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class StartOrderService {
    public static void main(String[] args) {
        SpringApplication.run(StartOrderService.class,args);
    }

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    //重新创建一个均衡策略,表示不使用默认
   /* @Bean
    public IRule getIReule(){ //通过获取一个IRule对象,
        return  new RandomRule();  //达到的目的,用我们重新选择的随机,替代默认的轮训方式
    }*/
}

 

 

八、配置中心config

1准备仓库码云

 

2创建一个配置中心

<dependencies>

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
  </dependency>
</dependencies>

<dependencyManagement>
  <dependencies>
    <!--springCloud依赖-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>Greenwich.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

 

3创建配置文件

#应用名称

spring.application.name=config-server

#配置端口号

server.port=8888

spring.cloud.config.server.git.uri=https://gitee.com/fenglichao/cloud-config.git

spring.cloud.config.server.git.searchPaths=respo

spring.cloud.config.label=master

spring.cloud.config.server.git.username=

spring.cloud.config.server.git.password=

4创建启动类

@SpringBootApplication

@EnableConfigServer

public class StartConfigServer {

public static void main(String[] args) {

SpringApplication.run(StartConfigServer.class,args);

}

}

 

八、配置客户端

1加入config依赖

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-config</artifactId>

</dependency>

2配置文件

spring.application.name=config-client

spring.cloud.config.label=master

spring.cloud.config.profile=dev

#配置中心地址

spring.cloud.config.uri=http://localhost:8888/

server.port=9999

3获取配置文件中值

@RestController
public class ConfigController {


    @Value("${userName}")
    String userName;

    @RequestMapping("/getConfig")
    public String getConfig(){
       return userName;
    }
}

 

 

 

posted @ 2020-04-08 10:34  F阿东  阅读(580)  评论(0)    收藏  举报