SpringCloud如何创建一个服务提供者provider

前几篇主要集中在注册中心eureka的使用上,接下来可以创建服务提供者provider来注册到eureka。

demo源码见: https://github.com/Ryan-Miao/spring-cloud-Edgware-demo/tree/master/provider-demo

为了方便版本控制,接下来的项目都是基于https://github.com/Ryan-Miao/spring-cloud-Edgware-demo 这个parent配置的。

创建子moudle provider-demo

创建一个子module,项目名叫provider-demo. 填充springboot和springcloud依赖

<dependencies>
  <!--springboot 依赖start-->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-devtools</artifactId>
   <optional>true</optional>
  </dependency>
  <dependency>
   <groupId>com.fasterxml.jackson.datatype</groupId>
   <artifactId>jackson-datatype-jsr310</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-eureka</artifactId>
  </dependency>
  <!--springboot 依赖结束-->

  <dependency>
   <groupId>io.springfox</groupId>
   <artifactId>springfox-swagger2</artifactId>
  </dependency>
  <dependency>
   <groupId>io.springfox</groupId>
   <artifactId>springfox-swagger-ui</artifactId>
  </dependency>

  <!--工具类 start-->
  <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
  </dependency>
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
  </dependency>

  <dependency>
   <groupId>net.logstash.logback</groupId>
   <artifactId>logstash-logback-encoder</artifactId>
  </dependency>
  <!--工具类end-->

 </dependencies>

spring-boot-starter-web 提供web能力,必须spring-boot-starter-actuator 提供项目统计和基础的监控endpoint, 想要使用spring-boot-admin监控就必须添加了 spring-boot-devtools 开发模式 jackson-datatype-jsr310 可以解决Java8新的时间APILocalDate解体 spring-cloud-starter-eureka eureka客户端,负责维护心跳和注册 swagger 提供Restful契约 lombok 看起来很清爽的编译级别getter setter工具 guava 大而全的Java必备类库 logstash-logback-encoder 想要收集日志到ELK,使用这个appender

启动类

@EnableDiscoveryClient
@SpringBootApplication
public class ProviderDemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(ProviderDemoApplication.class, args);
  }

}

@EnableDiscoveryClient 来启用服务注册

这个ProviderDemoApplication应该放置于项目包的最外层,因为@SpringbootAppliatin包含了@ComponentScan的注解,默认扫描本类包下,否则必须手动指定scan。

Swagger

swagger就是一个配置类

@EnableSwagger2
@Configuration
public class SwaggerConfiguration {

  private ApiInfo apiInfo() {
    return new ApiInfoBuilder()
      .title("服务提供者 API")
      .description("提供用户信息查询")
      .termsOfServiceUrl("")
      .version("1.0.0")
      .build();
  }

  /**
   * 定义api配置.
   */
  @Bean
  public Docket api() {
    return new Docket(DocumentationType.SWAGGER_2)
      .select()
      .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
      .build()
      .apiInfo(apiInfo());
  }

}

对于swagger页面的路由,需要我们来引导下:

创建一个controller来导航

@Controller
public class HomeController {
  @GetMapping(value = {"/api", "/"})
  public String api() {
    return "redirect:/swagger-ui.html";
  }

}

来一个Controller 接口

@Api
@RestController
@RequestMapping("/api/v1/users")
public class UserController{

  private List<User> users = Lists.newArrayList(
    new User(1, "谭浩强", 100, LocalDate.now()),
    new User(2, "严蔚敏", 120, LocalDate.now()),
    new User(3, "谭浩强", 100, LocalDate.now()),
    new User(4, "James Gosling", 150, LocalDate.now()),
    new User(6, "Doug Lea", 150, LocalDate.now())
  );

  @GetMapping("/")
  public List<UserVo> list() {
    return users.stream()
      .map(u -> new UserVo(u.getId(), u.getName(), u.getAge(), u.getBirth()))
      .collect(Collectors.toList());
  }
}

一些简单的环境配置

application.yml

spring:
 application:
  name: provider-demo
 jackson:
  serialization:
   WRITE_DATES_AS_TIMESTAMPS: false
  default-property-inclusion: non_null

#服务过期时间配置,超过这个时间没有接收到心跳EurekaServer就会将这个实例剔除
#注意,EurekaServer一定要设置eureka.server.eviction-interval-timer-in-ms否则这个配置无效,这个配置一般为服务刷新时间配置的三倍
#默认90s
eureka.instance.lease-expiration-duration-in-seconds: 15
#服务刷新时间配置,每隔这个时间会主动心跳一次
#默认30s
eureka.instance.lease-renewal-interval-in-seconds: 5

server:
 port: 8082

springfox:
 documentation:
  swagger:
   v2:
    path: /swagger-resources/api-docs

log:
 path: logs

application-dev.yml

management:
 security:
  enabled: false
eureka:
 client:
  serviceUrl:
   defaultZone: http://localhost:8761/eureka/

logstash:
 url: localhost:4560

这里需要提一点,由于我集成了logstash, 所以必须安装好logstash, 见ELK入门使用。 当然可以跳过,只要不提供logback.xml的配置就行,把依赖中logstash移除即可。

Log配置

默认采用logback作为日志框架,简单配置如下,对于不想使用logstash的,移除logstash的appender即可。

在resource下新建logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

 <springProperty scope="context" name="appName" source="spring.application.name"
  defaultValue="unknown"/>
 <springProperty scope="context" name="log.path" source="log.path"
  defaultValue="logs"/>
 <springProperty scope="context" name="logstashurl" source="logstash.url"
  defaultValue="localhost:4560"/>

 <include resource="org/springframework/boot/logging/logback/base.xml"/>
 <!--输出到控制台-->
 <appender name="console" class="ch.qos.logback.core.ConsoleAppender">LoggingInterceptor

  <encoder>
   <pattern>%d{HH:mm:ss.SSS} %X{req.remoteHost} %X{req.requestURI}
    ${appName} [%thread] %-5level %logger{36} - %msg%n
   </pattern>
  </encoder>
 </appender>

 <!--输出到文件-->
 <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
   <fileNamePattern>${log.path}/${appName}.%d{yyyy-MM-dd}.log</fileNamePattern>
  </rollingPolicy>
  <encoder>
   <pattern>%d{HH:mm:ss.SSS} ${appName} %X{req.remoteHost} %X{req.requestURI}
    %X{req.userAgent}
    %X{req.method} - [%thread] %-5level %logger{36} - %msg%n
   </pattern>
  </encoder>
 </appender>

 <!-- 输出到logstash-->
 <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
  <destination>${logstashurl}</destination>
  <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/>
 </appender>

 <springProfile name="dev">
  <root level="info">
   <appender-ref ref="console"/>
   <appender-ref ref="file"/>
   <appender-ref ref="LOGSTASH"/>
  </root>

 </springProfile>
 <springProfile name="test, prod">
  <root level="info">
   <appender-ref ref="file"/>
   <appender-ref ref="LOGSTASH"/>
  </root>
 </springProfile>
</configuration>

启动

确保eureka已启动,admin最好也启动,方便查看app状态,ELK的日志系统也最好可以使用。当然,只有eureka是刚需。

编译打包

mvn clean install package spring-boot:repackage

运行main方法,指定profile为dev, 可以在idea中编辑运行配置,添加参数

--spring.profiles.active=dev

或者命令行jar启动

代码如下:

java -Xms256m -Xmx1g -XX:+UseG1GC -jar ./target/provider-demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev

启动后,访问eureka

访问admin

访问provider-demo

暴露我们的API给consumer

既然有服务提供者,必然是为了consumer消费。consumer应该如何消费?手动调用这个http请求即可。前面提到swagger Restful契约,就是服务提供者提供请求访问的参数和要求。consumer如果手动去开发这个client必然耗时,而且容易出错。所以,作为服务提供者,理应提供sdk或者client给consumer来用。

在spring cloud技术体系中,远程调用自然是重中之重。目前我找到的具体用法为Feign+Ribbon+Hystrix.

通过Feign的声明式接口对接,实现了consumer对provider的调用。ribbon客户端负载均衡,hystrix作健康熔断。

在这里,我们就首先要提供Feign的接口了。

把controller的api提炼成一个接口。首先,我们创建一个新的项目

https://github.com/Ryan-Miao/spring-cloud-Edgware-demo/tree/master/provider-api

将这个项目放到provider-demo的依赖列表里

<!--内部依赖-->
<dependency>
 <groupId>com.test</groupId>
 <artifactId>provider-api</artifactId>
 <version>0.0.1-SNAPSHOT</version>
</dependency>
<!--内部依赖end-->

抽离UserApi接口道provider-api项目中

@RequestMapping("/api/v1/users")
public interface UserApi {

  @GetMapping("/")
  List<UserVo> list();
}

在provider-demo的controller里改造如下

@Api
@RestController
public class UserController implements UserApi {

  private List<User> users = Lists.newArrayList(
    new User(1, "谭浩强", 100, LocalDate.now()),
    new User(2, "严蔚敏", 120, LocalDate.now()),
    new User(3, "谭浩强", 100, LocalDate.now()),
    new User(4, "James Gosling", 150, LocalDate.now()),
    new User(6, "Doug Lea", 150, LocalDate.now())
  );

  @Override
  public List<UserVo> list() {
    return users.stream()
      .map(u -> new UserVo(u.getId(), u.getName(), u.getAge(), u.getBirth()))
      .collect(Collectors.toList());
  }
}

这样,controller没有变化,只是被抽离了api路径。而独立出来的module provider-api就是我们给consumer提供的client。下一节使用consumer消费。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • springcloud gateway聚合swagger2的方法示例

    问题描述 在搭建分布式应用时,每个应用通过nacos在网关出装配了路由,我们希望网关也可以将所有的应用的swagger界面聚合起来.这样前端开发的时候只需要访问网关的swagger就可以,而不用访问每个应用的swagger. 框架 springcloud+gateway+nacos+swagger 问题分析 swagger页面是一个单页面应用,所有的显示的数据都是通过和springfox.documentation.swagger.web.ApiResponseController进行数据交互,

  • 解决Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程问题

    待解决的问题 Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程 解决办法 为spring session添加springSessionRedisTaskExecutor线程池. /** * 用于spring session,防止每次创建一个线程 * @return */ @Bean public ThreadPoolTaskExecutor springSessionRedisTaskExecutor(){ T

  • 5分钟快速创建spring boot项目的完整步骤

    前言 上一篇博客说了如何创建spring boot项目,但是有些同学会觉得有点麻烦,有没有什么快速学会能快速创建spring boot项目的方法,答案是肯定的.接下来我们就一起来快速创建一个spring boot项目并让它跑起来. 我们今天用两种方式创建,分别是在线创建和使用IntelliJ IDEA创建. 1 在线创建 1.1 在浏览器中打开https://start.spring.io/,我们看到的是如下图所示: 1.2 Project选择Maven Project,Language选择Ja

  • 使用Spring Boot创建Web应用程序的示例代码

    在这篇文章中,我们将探讨使用Spring Boot创建Web应用程序的细节. 我们将探索Spring Boot如何帮助你加速应用程序开发. 我们将使用Spring Boot构建一个简单的Web应用程序,并为其添加一些有用的服务. 1. 介绍 启动一个新项目的主要挑战之一是该项目的初始设置. 我们需要对不同的目录结构进行调用,并且需要确保我们遵循所有行业标准.对于使用Spring Boot创建Web应用程序,我们需要以下工具: 我们自己喜欢的IDE (我将使用IntelliJ) Maven JDK

  • 创建网关项目(Spring Cloud Gateway)过程详解

    创建网关项目 加入网关后微服务的架构图 创建项目 POM文件 <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springfram

  • Spring创建Bean的6种方式详解

    前言 本文讲解了在Spring 应用中创建Bean的多种方式,包括自动创建,以及手动创建注入方式,实际开发中可以根据业务场景选择合适的方案. 方式1: 使用Spring XML方式配置,该方式用于在纯Spring 应用中,适用于简单的小应用,当应用变得复杂,将会导致XMl配置文件膨胀 ,不利于对象管理. <bean id="xxxx" class="xxxx.xxxx"/> 方式2: 使用@Component,@Service,@Controler,@R

  • 详解Spring Cloud Gateway 限流操作

    开发高并发系统时有三把利器用来保护系统:缓存.降级和限流. API网关作为所有请求的入口,请求量大,我们可以通过对并发访问的请求进行限速来保护系统的可用性. 常用的限流算法比如有令牌桶算法,漏桶算法,计数器算法等. 在Zuul中我们可以自己去实现限流的功能 (Zuul中如何限流在我的书 <Spring Cloud微服务-全栈技术与案例解析>  中有详细讲解) ,Spring Cloud Gateway的出现本身就是用来替代Zuul的. 要想替代那肯定得有强大的功能,除了性能上的优势之外,Spr

  • Spring Boot 项目创建的详细步骤(图文)

    一. 简单介绍一下Spring Boot 世界惯例,在学习一个框架之前,我们需要了解一下这个框架的来历. 下面我们引用一下百度百科的解释. Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者 Spring Boo

  • SpringCloud如何创建一个服务提供者provider

    前几篇主要集中在注册中心eureka的使用上,接下来可以创建服务提供者provider来注册到eureka. demo源码见: https://github.com/Ryan-Miao/spring-cloud-Edgware-demo/tree/master/provider-demo 为了方便版本控制,接下来的项目都是基于https://github.com/Ryan-Miao/spring-cloud-Edgware-demo 这个parent配置的. 创建子moudle provider

  • 在ASP.NET 2.0中操作数据之六十:创建一个自定义的Database-Driven Site Map Provider

    导言: ASP.NET 2.0的网站地图(site map)功能允许页面开发者在一些持久介质(persistent medium),比如一个XML文件里,自己定义一个web程序的site map.一旦定义了之后,我们可以通过System.Web命名空间的SiteMap class类或某个Web导航控件,比如SiteMapPath, Menu, 或TreeView来对其进行访问.site map系统使用的是provider model模式,所以可以创建不同的site map,并将其应用到一个web

  • java如何创建一个jdbc程序详解

    JDBC简介 Java数据库连接(Java Database Connectivity,JDBC),是一种用于执行SQL语句的Java API,它由一组用Java编程语言编写的类和接口组成. JDBC为数据库开发人员提供了一个标准的API,使他们能够用纯Java API来编写数据库应用程序. 使用JDBC编写的程序能够自动地将SQL语句传送给相应的数据库管理系统. JDBC扩展了Java的功能,由于Java语言本身的特点,使得JDBC具有简单.健壮.安全.可移植.获取方便等优势. 我们在没有JD

  • python创建一个最简单http webserver服务器的方法

    本文实例讲述了python创建一个最简单http webserver服务器的方法.分享给大家供大家参考.具体实现方法如下: import sys import BaseHTTPServer from SimpleHTTPServer import SimpleHTTPRequestHandler Handler = SimpleHTTPRequestHandler Server = BaseHTTPServer.HTTPServer Protocol = "HTTP/1.0" if s

  • 使用Spring来创建一个简单的工作流引擎

    文章来源:matrix 作者:Steve Dodge 摘要 spring是支持控制反转编程机制的一个相对新的框架.本文把spring作为简单工作流引擎,将它用在了更加通用的地方.在对工作流简单介绍之后,将要介绍在基本工作流场景中基于Spring的工作流API的使用. 许多J2EE应用程序要求在一个和主机分离的上下文中执行处理过程.在许多情况下,这些后台的进程执行多个任务,一些任务依赖于以前任务的状态.由于这些处理任务之间存在相互依赖的关系,使用一套基于过程的方法调用常常不能满足要求.开发人员能够

  • 创建一个类Person的简单实例

    创建一个类Person,包含以下属性:姓名(name).年龄(age).朋友(friends数组).问候(sayhi方法,输出问候语,例如:"你好!").交朋友(addFriend方法,向friends里添加一个值),然后创建两个此类的实例:"小张",22,["小李","小王"],"你好!","James","James",24,["Ann",&q

  • jquery创建一个新的节点对象(自定义结构/内容)的好方法

    HTML 复制代码 代码如下: <!DOCTYPE html> <html> <head> <script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <meta charset=utf-8 /> <title>JsBin-在线js/css调试工具&

  • 创建一个在标题栏中没有“关闭”按钮的 HTA

    问: 您好,脚本专家!如何创建一个在标题栏中没有"关闭"按钮的 HTA? -- AK 答: 您好,AK.您知道,您的问题让我们陷入了道德和伦理的窘境.毕竟,假如我们给出此问题的答案:这个世界就有可能突然被大量无法关闭的 HTA 所淹没.在我们的眼前会出现这样一幅画面:无法关闭又不能停止的 HTA 疯狂地横扫整个陆地,并吞食沿途的所有系统资源.而我们脚本专家,将要对此负责.我们只是觉得无法在良心上背负这样一条的罪责. 但是,在我们的的良心上再多加一条罪责又会有什么不同呢?明确这一点后,我

  • 创建一个空的IBM DB2 ECO数据库的方法

    问:怎样才能创建一个空的 IBM DB2 ECO数据库? 答:一般情况下你需要一个空数据库作为存储 EcoSpace 的容器.Delphi 2005 提供了一张光盘,其中包括 IBM DB2 UDB 开发人员版.您可以使用 Control Center(可在 IBM DB2 General Administrator Tool 中找到).在 Control Center 中,可以使用树型视图来查看系统.DB2 实例和数据库.使用向导创建一个新的数据库,这将为您提供一个分为 7 步的向导,在那里只

  • 使用Vue.js创建一个时间跟踪的单页应用

    Vue.js很简单.正因为如此简单,人们常常认为其适合于小项目.虽然真正的Vue.js核心知识只是一个视图层库,实际上有一组工具,将使您能够使用Vue.js构建完整的大规模SPA(单页应用程序). SPA应用可以在不完全重新加载网页,产生一个更流畅的用户体验到的用户交互响应.还有好的副作用,SPA还鼓励后端专注于展示数据端点,这使得整体架构更加分离,并且对于其他类型的客户端可能是可重用的. 从开发人员的角度来看,SPA和传统的后端呈现应用程序之间的主要区别是,我们必须将客户端视为具有自己架构的应

随机推荐