• Spring Cloud的基本认识和使用Spring Cloud的基本教程(山东数漫江湖)


    认识Spring Cloud

    Spring Cloud简单来说就是一个微服务相关的框架,至于什么是微服务,简单来说就是一个整体项目由多个单独运行的小项目构成,每个小项目负责一个或多个功能,每个小项目有1个或者1个以上运行实例,项目之间可以相互调用。如果有接触Dubbo,那么就可以很容易理解,Dubbo是一个提供不同项目相互调用的框架,同时Dubbo需要依赖于Zookeeper,所以说Spring Cloud做的事和Dubbo类似,却又有很大不同,但是它们的目的确实相同的,那就是提供不同项目之间的调用和负载均衡

    Spring Cloud 常用组件

    Spring Cloud Eureka

    Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件中的一部分,它基于Netflix Eureka 做了二次分装,由两个组件组成:Eureka服务器和Eureka客户端。 Eureka服务器用作服务注册服务器。Eureka客户端是一个Java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支 持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡,其中Eureka Server角色相当于Dubbo的Zookeeper,Eureka Client相当于服务提供者和调用者

    Spring Cloud Zookeeper

    对Zookeeper的封装,使之能配置其它Spring Cloud的子项目使用

    Spring Cloud Zuul

    类似nginx,反向代理的功能,不过netflix自己增加了一些配合其他组件的特性。

    Spring Cloud Hystrix

    断路器可以防止一个应用程序多次试图执行一个操作,即很可能失败,允许它继续而不等待故障恢复或者浪费 CPU 周期,而它确定该故障是持久的。断路器模式也使应用程序能够检测故障是否已经解决。如果问题似乎已经得到纠正​​,应用程序可以尝试调用操作。

    Spring Cloud Security

    对Spring Security的封装,并能配合Netflix使用

    Spring Cloud Bus

    分布式消息队列,是对Kafka, MQ的封装

    Spring Cloud Config

    将配置信息中央化保存, 配置Spring Cloud Bus可以实现动态修改配置文件

    其他组件可以在官网或者中文网站查看

    中文文档:https://springcloud.cc/

    官方网站:http://projects.spring.io/spring-cloud/#quick-start

    使用Spring Cloud搭建简易微服务项目

    要使用Spring Cloud搭建项目,首先需要考虑微服务的基础结构,然后再根据基础结构来搭建项目 EurekaClient,ribbon,feignEurekaServer可以是一台或多台,EurekaClient也可以是一台或多台,同时EurekaClient既可以是服务提供者也可以调用者,对于doubbo比较熟悉的人,可以吧EurekaServer当做Zookeeper,EurekaClient为我们的项目,本文的demo是基于spring boot的,如果不会spring boot的可以去看看我之前的文章基于Maven的Springboot+Mybatis+Druid+Swagger2+mybatis-generator框架环境搭建

    创建EurekaServer

    EurekaServer的pom

    <?xml version="1.0" encoding="UTF-8"?>  
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>wang.raye</groupId>
        <artifactId>springcloudserver</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>springcloudServer</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.3.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>Dalston.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </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>
    
    
    </project>
    

    主要是对项目加入了eureka-server的支持

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

    application添加注解

    @EnableEurekaServer
    

    Application.java

    package wang.raye.springcloudserver;
    
    import org.springframework.boot.SpringApplication;  
    import org.springframework.boot.autoconfigure.SpringBootApplication;  
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @EnableEurekaServer
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    

    相对于普通的的Application只是对了一个注解而已,当然仅仅这样也不行,熟悉doubbo的人都知道Zookeeper是有端口的,所以我们需要在application.yml中配置好EurekaServer的端口

    配置如下:

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

    其中${}是可以用静态变量代替的,不过这里为了跟项目保持一致,所以直接用的项目的名字和端口,application.yml详细配置如下:

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

    访问http://localhost:8761 可以看到如下界面,显示EurekaServer当前状态EurekaServer状态

    创建EurekaClient

    为了显示效果,所以我们创建2个EurekaClient项目,2个项目相互调用,因为Spring Cloud支持2种调用方式,Ribbon和Feign,所以2个项目,我们分别用2种方式来调用,2种方式提供服务的方法都是相同的,只是在调用其他项目的方法上面稍有不同而已

    首先创建Ribbon方式的client

    ribbon

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>  
    <project xmlns="http://maven.apache.org/POM/4.0.0"  
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>wang.raye</groupId>
        <artifactId>springcloud.ribbon</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.3.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>Dalston.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</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-ribbon</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </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>
    
    
    </project>  
    

    其中

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

    是提供服务的相关依赖

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

    是调用方式的依赖,当然一个项目可以同时使用ribbon和feign2个方法调用

    application.java

    package wang.raye.springcloud.ribbon;
    
    import org.springframework.boot.SpringApplication;  
    import org.springframework.boot.autoconfigure.SpringBootApplication;  
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;  
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;  
    import org.springframework.context.annotation.Bean;  
    import org.springframework.web.client.RestTemplate;
    
    /**
     * Created by Raye on 2017/5/22.
     */
    @SpringBootApplication
    @EnableEurekaClient
    public class Application {  
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Bean
        @LoadBalanced
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
    }
    

    @EnableEurekaClient 是提供向注册中心表明此服务需要被注册的注解

    Conntroller.java

    package wang.raye.springcloud.ribbon;
    
    import org.springframework.beans.factory.annotation.Autowired;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.bind.annotation.RestController;  
    import org.springframework.web.client.RestTemplate;
    
    /**
     * Created by Raye on 2017/5/22.
     */
    @RestController
    public class Controller {
    
        @Autowired
        private RestTemplate template;
        @RequestMapping("hello")
        public String ribbon(String name){
            return template.getForObject("http://SERVICE-HI/ribbonhello?name="+name,String.class);
        }
    
        @RequestMapping("feignhello")
        public String hello(String name){
            return "hello "+name+" this is ribbon spring cloud";
        }
    }
    

    feignhello是被远程调用的接口,hello接口是远程调用另外一个项目的接口,其中RestTemplate 是配置文件写好就可以自动注入的,http://SERVICE-HI 其中SERVICE-HI是被调用的项目配置的名字,ribbonhello是接口地址

    application.yml

    eureka:  
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:  
      port: 8764
    spring:  
      application:
        name: service-ribbon
    

    eureka相关配置是配置的注册中心的地址,而service-ribbon是配置其他项目访问的地址的,ribbon访问这样配置就是ok 的了,直接运行Application.java就可以了,接下来看看feign方式的client

    fegin
    <?xml version="1.0" encoding="UTF-8"?>  
    <project xmlns="http://maven.apache.org/POM/4.0.0"  
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>wang.raye.springcloud</groupId>
        <artifactId>client</artifactId>
        <version>1.0-SNAPSHOT</version>
        <name>springcloudClient</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.3.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>Dalston.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</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.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </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>
    
    </project>  
    

    同理,如果需要feign方式调用,需要先添加依赖

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

    Application.java

    package wang.raye.springcloudclient;
    
    import org.springframework.boot.SpringApplication;  
    import org.springframework.boot.autoconfigure.SpringBootApplication;  
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    
    /**
     * Created by Raye on 2017/5/22.
     */
    @EnableEurekaClient
    @SpringBootApplication
    @EnableFeignClients
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    

    这里多了一个注解就是@EnableFeignClients,必须要这个注解,定义的接口才能正确注入引用类中的,有了Application.java类后,需要先定义一个远程调用服务器的接口类,如下:

    HelloService.java

    package wang.raye.springcloudclient;
    
    import org.springframework.cloud.netflix.feign.FeignClient;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.bind.annotation.RequestMethod;  
    import org.springframework.web.bind.annotation.RequestParam;
    
    /**
     * Fegin 可被调用的服务申明
     * Created by Raye on 2017/6/26.
     */
    @FeignClient(value = "service-ribbon")
    public interface HelloService {
    
        @RequestMapping(value = "/feignhello",method = RequestMethod.GET)
        String sayHelloFromRibbon(@RequestParam(value = "name") String name);
    }
    

    这里是定义了一个接口,但是具体接口实现是由远程实现的,也就是通过调用其他项目实现的,其中FeignClient注解的值跟ribbon调用的值一样,都是被调用项目的项目名字,RequestMapping就很明显了,跟Controller用的是同一个,不过这里是表明远程调用这个方法而已

    Controller.java

    package wang.raye.springcloudclient;
    
    import org.springframework.beans.factory.annotation.Autowired;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * feign调用的Controller
     * Created by Raye on 2017/6/26.
     */
    @RestController
    public class Controller {
    
        @Autowired
        private HelloService helloService;
        /**
         * 远程通过feign调用另外一个项目的方法
         * @param name
         * @return
         */
        @RequestMapping("hello")
        public String hello(String name){
            return helloService.sayHelloFromRibbon(name);
        }
    
        /**
         * 使用ribbon方式调用的方法
         * @param name
         * @return
         */
        @RequestMapping("ribbonhello")
        public String sayHello(String name){
            return "hello "+name+" this is feign spring cloud";
        }
    }
    

    在Controller中,直接自动注入HelloService就行了,具体实现Spring cloud已经帮我们实现了,只要配置是正确的就行了,同时ribbonhello是被第一个项目远程调用的方法,hello是远程调用第一个项目的接口,最后看看application.yml

    application.yml

    eureka:  
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:  
      port: 8762
    spring:  
      application:
        name: service-hi
    

    到此,第二个项目就完成了,最后启动3个项目,访问http://localhost:8762/hello?name=Raye 会返回hello Raye this is ribbon spring cloud,访问http://localhost:8764/hello?name=Raye 会返回hello Raye this is feign spring cloud

    结尾

    spring cloud最简单的基本使用就介绍完了,本文只是为大家介绍一下什么是spring cloud和spring cloud的基本使用,所以并没有深入介绍,另外附上本项目的代码地址

    oschina

    github

  • 相关阅读:
    怎么做程序?(摘录微博)
    ObjectiveC protocol & delegate
    iPhone网络编程之监视网络连接
    第二个iPhone应用程序:“Say Hello”
    NSNotificationCenter 的使用详解
    打字效果,自动换行的CCLabelTTF
    objectc's selector (forward)
    IOS触摸事件
    如何使用Android SDK Manager下载 SDK
    年月日三级级联
  • 原文地址:https://www.cnblogs.com/kkdn/p/8940888.html
Copyright © 2020-2023  润新知