zoukankan      html  css  js  c++  java
  • springcloud基础入门

    先了解一下springcloud和dubbo的区别

    dubbo由于是二进制的传输,占用带宽会更少

    springCloud是http协议传输,带宽会比较多,同时使用http协议一般会使用JSON报文,消耗会更大

    dubbo的开发难度较大,原因是dubbo的jar包依赖问题很多大型工程无法解决

    springcloud的接口协议约定比较自由且松散,需要有强有力的行政措施来限制接口无序升级

    dubbo的注册中心可以选择zk,redis等多种,springcloud的注册中心只能用eureka或者自研

    springcloud的最大的特点是可以很好的和restful模式进行交互

    dubbo是基于rpc的

     

    在开始SpringCloud之前,先看一下一个简单的服务提供者和服务消费者。服务提供者提供一个REST风格的HTTP接口给服务消费者。

    1.1 普通的提供者

    1.1.1 pom.xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath/>
    </parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    1.1.1 关键代码

    package com.test.springcloud.provider.pojo;
    
    public class User {
        private Long id;
        private String username;
        //getter/setter略
    
    }

    Controller

    package com.test.springcloud.provider.controller;
    
    import com.test.springcloud.provider.pojo.User;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
        @GetMapping("/simple/{id}")//rest 风格,微服务一般都使用 rest 风格
        public User findById(@PathVariable Long id) {
            User user=new User();
            user.setId(id);
            user.setUsername("hello "+id);
            return user;
        }

    1.1.1 application.yml

    server:
      port: 8081

    1.1 普通的消费者

    1.1.1 pom.xml

    parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.13.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
       <java.version>1.8</java.version>
    </properties>
    <dependencies>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
       </dependency>
    </dependencies>
    
    <build>
       <plugins>
          <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
       </plugins>
    </build>

    实体类:

    package com.test.springcloud.consumer.pojo;
    
    public class User {
        private Long id;
        private String username;
        //getter/setter略
    }

    Controller

    package com.test.springcloud.consumer.controller;
    
    import com.test.springcloud.consumer.pojo.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    public class UserController {
        @Autowired
        private RestTemplate restTemplate;// rest 请求模板类
    
        @Value("${user.userServicePath}")//从配置文件中读取指定属性,名字和配置中保持一致即可
        private String userServicePath;
    
        @GetMapping("/user/{id}")
        public User findById(@PathVariable Long id) {
            //调用指定的地址,传递参数过去,将返回的数据解析为 user 格式
            // return this.restTemplate.getForObject("http://localhost:7900/simple/"+ id, User.class);//硬编码,不好
            return this.restTemplate.getForObject(this.userServicePath + id, User.class);//通过配置文件注入地址的方式
        }
    }

    启动类

    package com.test.springcloud.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    public class SpringcloudTestConsumerApplication {
       @Bean
       public RestTemplate restTemplate() {
          return new RestTemplate();
       }
       public static void main(String[] args) {
          SpringApplication.run(SpringcloudTestConsumerApplication.class, args);
       }
    }

    1.1.1 application.yml

    server:
      port: 8082
    userPath: http://localhost:8080/user/

    1.1 Eureka

    在消费者调用服务的时候,服务提供者的地址是以硬编码的形式写在配置文件中的。如果服务端迁移就需要改变地址。我们可以将服务注册到Eureka,消费者不必关心提供者的真实地址,通过Eureka中的服务名直

    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.13.RELEASE</version>
       <relativePath/>
    </parent>
    
    <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
       <java.version>1.8</java.version>
       <spring-cloud.version>Edgware.SR2</spring-cloud.version>
    </properties>
    
    <dependencies>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
       </dependency>
    
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
       </dependency>
    </dependencies>
    
    <dependencyManagement>
       <dependencies>
          <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>${spring-cloud.version}</version>
             <type>pom</type>
             <scope>import</scope>
          </dependency>
       </dependencies>
    </dependencyManagement>
    
    <build>
       <plugins>
          <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
       </plugins>
    </build>

    接调用服务即可。

    1.1.1 启动类

    在启动类上增加@EnableEurekaServer注解

    server:
      port: 8083

    eureka:
      instance:
        hostname: localhost
      client:
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    启动8083端口访问

    能看见一个管理的后台

    1.1.1 修改服务提供者

    pom.xml中添加SpringCloud的引用

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    启动类上添加注解@EnableEurekaClient:

    yml配置文件

    server:
      port: 8081
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8083/eureka/
    spring:
      application:
        name: service-provider  #这个名字就是调用服务时的名字

    1.1.1 修改消费者

    pom.xml同提供者一样

    启动类添加注解@EnableEurekaClient还有restTemplate上的@LoadBalanced

    完整的application.yml

    erver:
      port: 8082
    user: #此处 user没有任何含义,主要是一个名字而已
      #即便在这里也类似于硬编码, 还是不够灵活,定义提供者的位置
      #userServicePath: http://localhost:8081/simple/
      userServicePath: http://SERVICE-PROVIDER/simple/
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8083/eureka/
    spring:
      application:
        name: service-comsumer

    1.1 ribbon负载均衡

    在消费者中添加依赖:

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-ribbon</artifactId>
    </dependency>

    启动两次提供者(一个运行main方法,一个maven启动),修改端口,模拟同一个服务部署在不同的服务器上,如端口为8084。稍稍修改一些controller中的代码,区分两个服务:

    然后访问

    1. Feign

    Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。

    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.13.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
       <java.version>1.8</java.version>
       <spring-cloud.version>Edgware.SR2</spring-cloud.version>
    </properties>
    
    <dependencies>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-eureka</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-feign</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
       </dependency>
    </dependencies>
    
    <dependencyManagement>
       <dependencies>
          <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>${spring-cloud.version}</version>
             <type>pom</type>
             <scope>import</scope>
          </dependency>
       </dependencies>
    </dependencyManagement>
    
    <build>
       <plugins>
          <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
       </plugins>
    </build>

    启动类添加@EnableEurekaClient注解和@EnableFeignClients

    1.1 service

    package com.test.springcloud.feign.consumer.service;
    
    import com.test.springcloud.feign.consumer.pojo.User;
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    @FeignClient(value = "SERVICE-PROVIDER")
    public interface UserService {
        @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
        User getUserById(@PathVariable(value = "id") Long id);
    }

    @FeignClient的值是服务提供者在Eureka上的名字。

    方法上@RequestMapping的值是请求服务提供者时的路径。参数的传递方式和SpringMVCController接收参数时语法一样,如@PathVariable,@RequestParam

    User类同服务提供者中的一样。

    1.1 Controller

    package com.test.springcloud.feign.consumer.controller;
    
    import com.test.springcloud.feign.consumer.pojo.User;
    import com.test.springcloud.feign.consumer.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
        @Autowired
        private UserService userService;
    
        @RequestMapping(value = "/test", method = RequestMethod.GET)
        public User sayHi(@RequestParam Long id) {
            return userService.getUserById(id);
        }
    }

    1.1 application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8083/eureka/
    server:
      port: 8085
    spring:
      application:
        name: service-feign
    

      

    1. 断路器Hystrix

    1.1 Ribbon使用断路器

    ribbon的消费者工程中加入断路器依赖:

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>

    启动类上添加注解@EnableHystrix

    启动项目,在服务提供者挂掉的时候,会看到提示信息:

     

    如果不做熔断,会在请求服务提供者超时之后报错:

     

     1.2Feign使用熔断器

    在yml配置文件增默认自带熔断器打开

    feign:
      hystrix:
        enabled: true

    在消费的service层修改

    @FeignClient(value = "SERVICE-PROVIDER", fallback = TestServiceFallback.class)
    public interface TestService {
        @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
        User getUserById(@PathVariable(value = "id") Integer id);
    
    }

    创建TestService的实现类TestServiceFallback

    @Component
    public class TestServiceFallback implements TestService {
        @Override
        public User getUserById(Integer id) {
            User user = new User();
            user.setId(-2);
            user.setName("server error2");
            return user;
        }

    1.3 Hystrix Dashboard (Hystrix 仪表盘)

     在pom中添加依赖(feign和robbin)

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    </dependency>

    再启动类加

    @EnableHystrix
    @EnableHystrixDashboard注解

    启动访问localhost:port/hystrix

    访问服务的提供者 能看到这个界面可以清晰的看到这个请求的成功率和失败率

     

    1. 路由Zuul

    新建工程pom配置

    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.13.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
       <java.version>1.8</java.version>
       <spring-cloud.version>Edgware.SR3</spring-cloud.version>
    </properties>
    
    <dependencies>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-eureka</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-zuul</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
       </dependency>
    </dependencies>
    
    <dependencyManagement>
       <dependencies>
          <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>${spring-cloud.version}</version>
             <type>pom</type>
             <scope>import</scope>
          </dependency>
       </dependencies>
    </dependencyManagement>
    
    <build>
       <plugins>
          <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
       </plugins>
    </build>

    yml文件的配置

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8083/eureka/
    server:
      port: 8086
    spring:
      application:
        name: service-zuul
    zuul:
      routes:
        api-a:
          path: /api-a /**
          serviceId: service-consumer
        api-b:
          path: /api-b /**
          serviceId: service-feign

    routes定义了请求转发的规则。pathurl访问路径,serviceId是对应的Eureka中的服务

    http://localhost:8086/api-a/user/1会发送到service-consumer对应的工程

    http://localhost:8086/api-b/test?id=2会发送到feign的工程

    启动类:

    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy
    public class Zuul0723Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Zuul0723Application.class, args);
        }
    }
    努力提高自己的技术,不忘初心
  • 相关阅读:
    线性筛素数
    redis集成springmvc
    shiro登录权限认证
    jQuery插件
    maven多项目配置
    w
    触发器
    后悔了可以找我我们是朋友
    url upload data
    排队
  • 原文地址:https://www.cnblogs.com/blackCatFish/p/9637432.html
Copyright © 2011-2022 走看看