zoukankan      html  css  js  c++  java
  • SpringCloud入门实战(1)-Hello World

    Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。本文主要介绍Spring Cloud的基本使用,文中使用到的软件版本:Spring Boot 2.2.5.RELEASE、Spring Cloud Hoxton.SR3、Java 1.8.0_191。

    1、项目结构

    使用maven来管理工程,工程里包含多个模块:注册中心(scdemo-eureka)、服务提供者(scdemo-server)、服务调用者(scdemo-client)、网关(scdemo-gateway),差不多下面的样子:

    2、根工程(scdemo)

    跟功能只有一个pom文件,用于定义Spring Boot、Spring Cloud及其他一些框架的版本信息。

    scdemo/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>com.inspur</groupId>
        <artifactId>scdemo</artifactId>
        <version>1.0</version>
        <modules>
            <module>scdemo-eureka</module>
            <module>scdemo-srever</module>
            <module>scdemo-client</module>
            <module>scdemo-gateway</module>
        </modules>
        <packaging>pom</packaging>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.5.RELEASE</version>
            <relativePath />
        </parent>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Hoxton.SR3</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>

    3、注册中心(scdemo-eureka)

    3.1、scdemo/scdemo-eureka/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">
        <parent>
            <artifactId>scdemo</artifactId>
            <groupId>com.inspur</groupId>
            <version>1.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>scdemo-eureka</artifactId>
    
        <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>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    3.2、application.yml

    spring:
      application:
        name: scdemo-eureka
    
    server:
      port: 9000
    
    eureka:
      instance:
        prefer-ip-address: true
        #hostname: localhost
      client:
        register-with-eureka: false
        fetch-registry: false
        service-url:
          defaultZone: http://localhost:${server.port}/eureka
      server:
        enable-self-preservation: false

    3.3、启动类

    package com.inspur.scdemo.eureka;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaApplication.class, args);
        }
    }

    3.4、控制台地址

    启动后,控制台地址为:http://localhost:9000/

    4、服务提供者(scdemo-server)

    4.1、scdemo/scdemo-server/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">
        <parent>
            <artifactId>scdemo</artifactId>
            <groupId>com.inspur</groupId>
            <version>1.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>scdemo-srever</artifactId>
    
        <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-client</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    4.2、application.yml

    spring:
      application:
        name: scdemo-server
      cloud:
        loadbalancer:
          ribbon:
            enabled: false
    server:
      port: 9001
      servlet:
        context-path: /
    eureka:
      instance:
        prefer-ip-address: true
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://localhost:9000/eureka/

    4.3、启动类

    package com.inspur.scdemo.server;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class ServerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServerApplication.class, args);
        }
    }

    4.4、编写Controller

    package com.inspur.scdemo.server.controller;
    
    import com.inspur.scdemo.server.entity.CallResult;
    import com.inspur.scdemo.server.entity.User;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
        private Logger logger = LoggerFactory.getLogger(UserController.class);
        
        @RequestMapping("/addUser")
        public CallResult<User> addUser(@RequestBody User user) {
            logger.info(user.toString());
            //TODO: insert to db
            user.setId(1000L);
            user.setName("server-" + user.getName());
            CallResult<User> result = new CallResult<>();
            result.setResult(user);
            return result;
        }
        
        @RequestMapping("/getUser")
        public CallResult<User> getUser(long id) {
            logger.info(id + "");
            //TODO: select from db
            User user = new User();
            user.setId(id);
            user.setName("server-马云");
            user.setAddress("杭州");
            CallResult<User> result = new CallResult<User>();
            result.setResult(user);
            return result;
        }
    }

    5、服务调用者(scdemo-client)

    5.1、scdemo/scdemo-client/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">
        <parent>
            <artifactId>scdemo</artifactId>
            <groupId>com.inspur</groupId>
            <version>1.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>scdemo-client</artifactId>
    
        <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-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    5.2、application.yml

    spring:
      application:
        name: scdemo-client
      cloud:
        loadbalancer:
          ribbon:
            enabled: false
    server:
      port: 9002
      servlet:
        context-path: /
    eureka:
      instance:
        prefer-ip-address: true
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://localhost:9000/eureka
    
    feign:
      hystrix:
        enabled: true

    5.3、启动类

    package com.inspur.scdemo.client;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class ClientApplication {
        public static void main(String[] args) {
            SpringApplication.run(ClientApplication.class, args);
        }
    }

    5.4、编写Feign接口调用服务端

    package com.inspur.scdemo.client.feign;
    
    import com.inspur.scdemo.client.entity.CallResult;
    import com.inspur.scdemo.client.entity.User;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @FeignClient(name = "scdemo-server")
    public interface IUserFeign {
        @PostMapping("/user/addUser")
        CallResult<User> addUser(@RequestBody User user);
    
        @PostMapping("/user/getUser")
        CallResult<User> getUser(@RequestParam("id") long id);
    }

    5.5、编写Controller

    package com.inspur.scdemo.client.controller;
    
    import com.inspur.scdemo.client.entity.CallResult;
    import com.inspur.scdemo.client.entity.User;
    import com.inspur.scdemo.client.feign.IUserFeign;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
        private Logger logger = LoggerFactory.getLogger(UserController.class);
        @Autowired
        private IUserFeign userFeign;
        
        @RequestMapping("/addUser")
        public CallResult<User> addUser(String name, String address) {
            logger.info("name={},address={}", name, address);
            CallResult<User> result = new CallResult<>();
            try {
                User user = new User();
                user.setName(name);
                user.setAddress(address);
                CallResult<User> resultServer = userFeign.addUser(user);
                logger.info("server返回结果:{}" + resultServer);
    
                User user2 = resultServer.getResult();
                user2.setName("client-" + user2.getName());
                result.setResult(user2);
            } catch (Exception e) {
                result = new CallResult<User>(-1, "发生异常");
                e.printStackTrace();
            }
            return result;
        }
        
        @RequestMapping("/getUser")
        public CallResult<User> getUser(long id) {
            logger.info(id + "");
            
            CallResult<User> result = null;
            try {
                result = userFeign.getUser(id);
            } catch (Exception e) {
                result = new CallResult<User>(-1, "发生异常");
                e.printStackTrace();
            }
            return result;
        }
    }

    6、网关(scdemo-gateway)

    6.1、scdemo/scdemo-gateway/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">
        <parent>
            <artifactId>scdemo</artifactId>
            <groupId>com.inspur</groupId>
            <version>1.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>scdemo-gateway</artifactId>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
        </dependencies>
    </project>

    6.2、application.yml

    spring:
      application:
        name: scdemo-gateway
      cloud:
        loadbalancer:
          ribbon:
            enabled: false
        gateway:
          discovery:
            locator:
              enabled: false #是否开启服务注册和发现功能;将为每一个服务创建一个router,这个router把以服务名开头的请求路径转发到对应的服务上
              lower-case-service-id: true #将请求路径上的服务名转为小写
          routes:
            - id: client
              uri: lb://scdemo-client
              predicates:
                - Path=/scdemo-client/**
              filters:
                - StripPrefix=1 #路由时会去除/scdemo-client
    
    server:
      port: 9006
      servlet:
        context-path: /
    eureka:
      instance:
        prefer-ip-address: true
      client:
        register-with-eureka: false
        fetch-registry: true
        service-url:
          defaultZone: http://localhost:9000/eureka/

    6.3、启动类

    package com.inspur.scdemo.gateway;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    public class GatewayApplication {
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }
    }

    7、测试

    分别启动各个模块。

    7.1、查看注册的服务

     打开http://localhost:9000/,可以看到注册的服务:

    7.2、访问服务调用者的Controller

    打开http://localhost:9002/user/addUser?name=a&address=b

    可以看到服务调用者的后台日志,成功调用了服务提供者:

     页面也返回正确结果:

    7.3、通过网关访问服务调用者的Controller

    打开http://localhost:9006/scdemo-client/user/addUser?name=a&address=b,页面也返回正确结果:

  • 相关阅读:
    六种简单易理解的排序算法
    leetcode-數組篇
    leetcode-字符串篇
    java8 Optional优雅非空判断
    md2all 简单实用
    zooleeper面试题
    深入理解 JVM锁 与 分布式锁
    redission 高性能分布式锁
    Java传统 定时任务
    关于Zookeeper
  • 原文地址:https://www.cnblogs.com/wuyongyin/p/13434660.html
Copyright © 2011-2022 走看看