sbc(一)SpringBoot+SpringCloud初探

作者: crossoverJie | 来源:发表于2017-06-27 11:11 被阅读3219次

    前言

    sb1.jpg

    有看过我之前的SSM系列的朋友应该有一点印象是非常深刻的。

    那就是需要配置的配置文件非常多,什么Springmybatisredismq之类的配置文件非常多,并且还存在各种版本,甚至有些版本还互不兼容。其中有很多可能就是刚开始整合的时候需要配置,之后压根就不会再动了。

    鉴于此,Spring又推出了又一神器SpringBoot.

    它可以让我们更加快速的开发Spring应用,甚至做到了开箱即用。
    由于在实际开发中我们使用SpringBoot+SpringCloud进行了一段时间的持续交付,并在生产环境得到了验证,其中也有不少踩坑的地方,借此机会和大家分享交流一下。

    本篇我们首先会用利用SpringBoot构建出一个简单的REST API.
    接着会创建另一个SpringBoot项目,基于SpringCloud部署,并在两个应用之间进行调用。

    使用SpringBoot构建REST API

    我们可以使用Spring官方提供的初始化工具帮我们生成一个基础项目:http://start.spring.io/,如下图所示:

    sb2.jpg

    填入相应信息即可。由于只是要实现REST API所以这里只需要引用web依赖即可。

    将生成好的项目导入IDE(我使用的是idea)中,目录结构如下;

    sb3.jpg
    • 其中的SbcUserApplication是整个应用的入口。
    • resource/application.properties这里是存放整个应用的配置文件。
    • 其中的statictemplates是存放静态资源以及前端模板的地方,由于我们采用了前后端分离,所以这些目录基本上用不上了。

    通过运行SbcUserApplication类的main方法可以启动SpringBoot项目。

    接着在PostMan中进行调用,看到以下结果表明启动成功了:

    springBoot01.jpg

    这样一看是不是要比之前用Spring+SpringMVC来整合要方便快捷很多。

    创建另一个SpringBoot项目

    当我们的项目采用微服务构建之后自然就会被拆分成N多个独立的应用。比如上文中的sbc-user用于用户管理。这里再创建一个sbc-order用户生成订单。

    为了方便之后的代码复用,我将common包中的一些枚举值、工具类单独提到sbc-common应用中了,这样有其他应用要使用这些基础类直接引入这个依赖即可。

    <dependency>
        <groupId>com.crossoverJie</groupId>
        <artifactId>sbc-common</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </dependency>
    

    创建步骤和上文差不多,这里就不再赘述了。
    其中有一个order/getOrderNo的服务,调用结果如下:

    springBoot02.jpg

    之后会利用SpringCloud来将两个服务关联起来,并可以互相调用。

    使用SpringCloud进行分布式调用

    搭建eureka注册中心

    既然是要搭建微服务那自然少不了注册中心了,之前讲的dubbo采用的是zookeeper作为注册中心,SpringCloud则采用的是Netflix Eureka来做服务的注册与发现。

    新建一个项目sbc-service,目录结构如下:

    springBoot03.jpg

    核心的pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.1</version>
        </dependency>
    
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Brixton.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    

    非常easy,只需要引入eureka的依赖即可。
    然后在入口类加入一个注解@EnableEurekaServer,即可将该项目作为服务注册中心:

    package com.crossoverJie.service;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaApplication {
        private final static Logger logger = LoggerFactory.getLogger(EurekaApplication.class);
        public static void main(String[] args) {
    
            SpringApplication.run(EurekaApplication.class, args);
            logger.info("SpringBoot Start Success");
        }
    
    }
    

    接着修改配置文件application.properties:

    server.port=8888
    
    # 不向注册中心注册自己
    eureka.client.register-with-eureka=false
    
    # 不需要检索服务
    eureka.client.fetch-registry=false
    
    eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
    

    配置一下端口以及注册中心的地址即可。
    然后按照正常启动springBoot项目一样启动即可。

    在地址栏输入http://localhost:8888看到一下界面:

    springBoot04.jpg

    当然现在在注册中心还看不到任何一个应用,下面需要将上文的sbc-user,sbc-order注册进来。

    向注册中心注册服务提供者

    只需要在application.properties配置文件中加上注册中心的配置:

    eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka/
    

    并在sbc-order的主类中加入@EnableDiscoveryClient注解即可完成注册服务。

    启动注册中心以及应用,在注册中心看到一下界面则成功注册:

    springBoot05.jpg

    消费注册中心的服务

    服务是注册上去了,自然是需要消费了,这里就简单模拟了在调用http://localhost:8080/user/getUser这个接口的时候getUser接口会去调用ordergetOrder服务。

    这里会用到另一个依赖:

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

    他可以帮我们做到客户端负载,具体使用如下:

    • 加入ribbon依赖。
    • 在主类中开启@LoadBalanced客户端负载。
    • 创建restTemplate类的实例
            @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
    • 使用restTemplate调用远程服务:
    
         @Autowired
        private RestTemplate restTemplate;
        
         @RequestMapping(value = "/getUser",method = RequestMethod.POST)
        public UserRes getUser(@RequestBody UserReq userReq){
            OrderNoReq req = new OrderNoReq() ;
            req.setReqNo("1213");
            //调用远程服务
            ResponseEntity<Object> res = restTemplate.postForEntity("http://sbc-order/order/getOrderNo", req, Object.class);
            logger.info("res="+JSON.toJSONString(res));
    
            logger.debug("入参="+ JSON.toJSONString(userReq));
            UserRes userRes = new UserRes() ;
            userRes.setUserId(123);
            userRes.setUserName("张三");
    
            userRes.setReqNo(userReq.getReqNo());
            userRes.setCode(StatusEnum.SUCCESS.getCode());
            userRes.setMessage("成功");
    
            return userRes ;
    
        }
    

    由于我的远程接口是post,所以使用了postForEntity()方法,如果是get就换成getForEntity()即可。

    注意这里是使用应用名sbc-order(配置于sbc-order的application.properties中)来进行调用的,并不是一个IP地址。

    启动注册中心、两个应用。
    PostMan调用getUser接口时控制台打印:

    2017-06-27 00:18:04.534  INFO 63252 --- [nio-8080-exec-3] c.c.sbcuser.controller.UserController    : res={"body":{"code":"4000","message":"appID不能为空","reqNo":"1213"},"headers":{"X-Application-Context":["sbc-order:8181"],"Content-Type":["application/xml;charset=UTF-8"],"Transfer-Encoding":["chunked"],"Date":["Mon, 26 Jun 2017 16:18:04 GMT"]},"statusCode":"OK","statusCodeValue":200}
    
    

    由于并没有传递appId所以order服务返回了一个错误,也正说明是远程调用到了该服务。

    总结

    ps:这里只是简单使用了ribbon来进行服务调用,但在实际的开发中还是比较少的使用这种方式来调用远程服务,而是使用Feign进行声明式调用,可以简化客户端代码,具体使用方式请持续关注。

    本次算是springBoot+springCloud的入门,还有很多东西没有讲到,之后我将会根据实际使用的一些经验继续分享SpringCloud这个新兴框架。

    项目地址:https://github.com/crossoverJie/springboot-cloud

    个人博客地址:http://crossoverjie.top

    https://camo.githubusercontent.com/67a26f8ff47324b0ac6d3846f8c65c2002e82d31/68747470733a2f2f6f6f6f2e306f302e6f6f6f2f323031372f30342f32352f353866663464356664396661332e6a7067

    相关文章

      网友评论

      本文标题:sbc(一)SpringBoot+SpringCloud初探

      本文链接:https://www.haomeiwen.com/subject/jlascxtx.html