SpringCloud简单入门示例

本文介绍SpringCloud微服务框架的基础应用,包括注册中心Eureka、网关Zuul及服务间调用等核心功能。通过实例展示了如何快速构建微服务架构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 注册中心eureka

2. 网关zuul

3.微服务应用

3.1 服务应用

3.2 消费者服务

3.3消费者发起调用的核心代码

总结


微服务框架之 springcloud 是最流行的,加上 springboot,很容易快速上手。spring cloud 有很多组件,比如 注册中心 eureka、负载均衡 ribbon、网关zuul、feign客户端、容错组件 Hystrix 等等。还有 RestTemplate 可以很容易的发起 restful api调用。由于 组件较多、并且 名字 看起来、写起来、读起来 都有点 不友好,就会觉得 学习 spring cloud 是不是很难?实际上,spring boot 做了完整的封装,对于使用者来说,基本上就是:1、引入 pom依赖jar 2、使用简单的注解 就能够玩起来了。对于其中的细节,还是需要研究一番,不然上线容易出问题。

1. 注册中心eureka

单独起一个 spring boot 服务

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wxj</groupId>
    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-server</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <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>

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

    <!-- Spring Cloud -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</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>

application.properties

spring.application.name=eureka-server
server.port=8761
# 由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己
#一定要配置为false,不然启动时会把自己当作客户端向自己注册,会报错
eureka.client.register-with-eureka=false
# 由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为 false
eureka.client.fetch-registry=false

应用启动类加注解:

@EnableEurekaServer // 开启eureka 服务

启动应用,一个 eureka 注册中心 就OK了。

2. 网关zuul

单独起一个 spring boot 服务

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wxj</groupId>
    <artifactId>gateway-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway-zuul</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <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>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>


        <!-- 微服务的注册与发现 -->
        <!-- eureka 客户端依赖包 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--zuul 网关 ,自动完成 负载均衡-->
        <!-- 说明在默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:
            http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/**会被转发到serviceId
            对应的微服务-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>
    <!-- Spring Cloud -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</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>

application.properties


spring.application.name=gateway-zuul-service
server.port=9083


#将 zuul 注册到 eureka
#Eureka服务的地址,在启动的时候需要将自身的信息注册到Eureka中去
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

# 采用IP注册
eureka.instance.preferIpAddress=true

# 定义实例ID格式
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

应用启动类加注解:

@EnableZuulProxy

启动应用,网关服务就OK了。

网关服务启动后,就可以通过网关服务 来请求 具体的服务。具体格式如下:

http://网关域名/具体服务名/具体服务的mapping

也就是说,把原本请求 具体服务的 url 中的 域名部分 替换成 网关服务的域名,就可以通过 网关服务来转发 请求。如果 微服务 有很多,消费端 就不用维护 具体的服务域名,只通过 网关域名就ok了,方便。

说明,网关功能是一个可选项,在实际使用时,可以使用网关,也可以不用网关。

3.微服务应用

在spring cloud中,微服务应用 都需要配置 eureka 的配置

3.1 服务应用

单独起一个 springboot 服务

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wxj</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <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>
        <!-- eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <!-- Spring Cloud -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</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>

application.properties

spring.application.name=user-service
server.port=8081

#Eureka服务的地址,在启动的时候需要将自身的信息注册到Eureka中去
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

# 采用IP注册
eureka.instance.preferIpAddress=true

# 定义实例ID格式
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

接口服务,自己定义一个。

启动服务

3.2 消费者服务

单独起一个 spring boot 服务,以下代码都是在消费者端写的

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wxj</groupId>
    <artifactId>article-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>article-service</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <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>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>


        <!-- 微服务的注册与发现 -->
        <!-- eureka 客户端依赖包 start-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- eureka 客户端依赖包 end-->

        <!-- 客户端侧 的负载均衡 -->
        <!-- ribbon相关包 被 eureka自动引入了 -->
        <!-- ribbon 依赖包 start-->
       <!-- <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-core</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-loadbalancer</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>io.reactivex</groupId>
            <artifactId>rxjava</artifactId>
            <version>1.0.10</version>
        </dependency>-->
        <!-- ribbon 依赖包 end-->



        <!-- spring cloud 继承 ribbon-->
        <!--<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>-->

        <!-- feign 声明式的API调用 ,不用 RestTemplate 拼接 URL-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!--Hystrix 容错 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <!-- Hystrix Dashboard可视化监控数据-->
        <!--<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>-->
    </dependencies>



    <!-- Spring Cloud -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</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>

application.properties

spring.application.name=article-service
server.port=9082


#Eureka服务的地址,在启动的时候需要将自身的信息注册到Eureka中去
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

# 采用IP注册
eureka.instance.preferIpAddress=true

# 定义实例ID格式
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

3.3消费者发起调用的核心代码

3.3.1 RestTemplate 直接调用

直接调用时,就是 直接请求目标服务。

 @Bean(name = "restTemplate")
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
 /**
     * 直接通过 url 调用服务
     */
    @Autowired
    @Qualifier("restTemplate")
    private RestTemplate restTemplate;
    @GetMapping("/article/callHello")
    public String callHello() {
        return restTemplate.getForObject("http://localhost:8081/user/hello", String.class);
    }

3.3.2 RestTemplate 通过服务名 负载均衡调用

这种方式,是通过 应用名称,到注册中心拿到服务列表,然后通过负责均衡策略来选择其中的一个服务进行请求。

    @Bean(name = "loadbalanceRestTemplate")
    @LoadBalanced  // 加上这个注解,就走的是 注册中心获取服务地址, 并且实现了 复制均衡
    public RestTemplate getRestTemplate2() {
        return new RestTemplate();
    }
/**
     * 通过 服务名  到 注册中心 获取服务 调用
     */
    @Autowired
    @Qualifier("loadbalanceRestTemplate")
    private RestTemplate loadbalanceRestTemplate;
    @GetMapping("/article/callHello2")
    public String callHello2() {
        return loadbalanceRestTemplate.getForObject("http://user-service/user/hello", String.class);
    }

3.3.3 feign 发起调用

这种方式,是通过 应用名称,到注册中心拿到服务列表,然后通过负责均衡策略来选择其中的一个服务进行请求。天然的支持了 负责均衡。

如果使用 RestTemplate,还需要加 @LoadBalanced注解才行。

消费端 定义一个feign客户端,代表 服务端提供的 服务

/**
 *  开启 feign 客户端,可指定服务端的 服务名,和注册中心保持一直
 */
@FeignClient(name = "user-service")
public interface ProviderFeignProxyClient {

    /**
     *
     * 服务端 提供的 服务 restful API
     * @param name
     * @return
     */
    @GetMapping("/house/data")
    HouseInfo hello(@RequestParam("name") String name);
}

使用feign客户端发起调用:

    /**
     * 在 启动类 加上 @EnableFeignClients 注解
     *
     * 在 消费者中 注入 feign client,即可。
     *
     * 可以 不用 RestTemplate 就能完成 调用了
     */
    @Autowired
    ProviderFeignProxyClient providerFeignProxyClient;


    @GetMapping("/feigntest")
    public HouseInfo feignTest(@RequestParam("name") String name){
        return providerFeignProxyClient.hello(name);
    }

3.3.4 开启 hystrix 功能

hystrix提供了服务保护功能,是一项可选功能。

只要加上 @HystrixCommand 注解就行了

    @HystrixCommand(
            // 设置 容错 方法
            fallbackMethod = "defaultInfo")
    @GetMapping("/hystrixTest")
    public HouseInfo hystrixTest(@RequestParam("name") String name){
        System.out.printf("hystrixTest");
        return providerFeignProxyClient.hello(name);
    }

    public HouseInfo defaultInfo(String name){
        return new HouseInfo(1L,"默认地址");
    }

总结

以上就是 spring cloud 入门示例,通过这个示例 可以 很好的 感受 spring cloud 提供的 微服务能力。spring cloud 提供了微服务解决方案,可以方便的搭建微服务系统,提高了开发效率。当然,在开发过程中,可能并不是全部使用了 spring cloud 提供的组件功能,比如 注册中心,eureka,可以使用 nacos;网关 zuul,可以使用 spring cloud gateway;熔断组件 hystrix,可以使用sentinel;可以选择 RestTemplate或者Feign,等等。这只是 入门,会用,想要提高,还需要 研究其实现原理。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值