使用Spring Cloud Netflix的Kotlin微服务:第2部分

在本系列的第1部分中,我们使用Kotlin介绍了Spring Cloud。我们讨论了Config Server,Discovery Server(Eureka),并创建了一个名为data-service的微服务,该服务已注册到Eureka并从onfig Server检索配置。最后,我们启动并运行了所有三个实例。

在本部分中,我们将展示如何在Spring Cloud中的微服务之间共享数据。正如我们所说,有许多方法可以根据业务需求实现数据共享。例如,如果我们想要基于REST的通信,我们可以使用Feign Client; 对于异步通信,我们可以使用消息代理等。在这个例子中,我们将使用Feign。我们将添加另一个名为user-service的微服务来包含有关用户的数据。我们将尝试通过从我们已经构建的数据服务中调用它来从API检索信息。为此,我们将使用Feign客户端。

Spring Cloud Feign

Feign是一个声明式Web服务客户端,是测试应用程序API的便捷方式,专注于创建测试以验证业务逻辑,而不是花时间在Web服务客户端的技术实现上。我们唯一需要描述的是如何通过提供URL,请求和响应正文,接受的标题等详细信息来访问远程API服务。Feign Client将负责实现细节。Feign使用Spring ApplicationContext创建组件集合,以将请求发送到Feign Client规范描述的远程服务端点。使用Feign时,Spring Cloud与Eureka和Ribbon集成,以提供负载均衡的HTTP客户端。我们在前一部分讨论了Eureka,让我们谈谈Ribbon。

功能区提供客户端负载平衡。负载平衡自动在为给定应用程序运行的节点数之间分配传入的应用程序流量。功能区组件提供了一组很好的配置选项,例如连接超时,重试算法等。它支持许多实现负载平衡的策略。

Feign还支持使用Hystrix API的回退机制。Spring Cloud的Hystrix提供了Circuit Breaker模式的实现。Hystrix监视方法的故障,如果故障累积到阈值,它将打开电路,以便后续呼叫自动失败。电路打开时,会将调用重定向到指定的回退方法。

现在,让我们通过使用Kotlin,Maven和依赖项创建Spring Boot应用程序来创建用户服务:

   <dependencies>
    <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-config</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib-jre8</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-reflect</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
      <groupId>de.flapdoodle.embed</groupId>
      <artifactId>de.flapdoodle.embed.mongo</artifactId>
    </dependency>
    <dependency>
      <groupId>de.flapdoodle.embed</groupId>
      <artifactId>de.flapdoodle.embed.process</artifactId>
      <version>2.0.5</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

我们添加了一个eureka-client依赖项,以使Eureka Server检测到用户服务,以及嵌入式MongoDB的依赖项,用于存储我们概念的一些用户数据。

在Application类中,我们添加了@EnableEurekaClient。

@SpringBootApplication
@EnableEurekaClient
class UserServiceApplication 
fun main(args: Array<String>) {
  runApplication<UserServiceApplication>(*args)
}

在resources文件夹中,我们添加了一个application.yml文件。

spring:
  application:
    name: "users"
  mongodb:
      embedded:
        version: 2.0.5
        features: sync_delay
eureka:
  client:
    healthcheck:
      enabled: true
server:
  port: 8082

声明了服务器端口,服务将向群集公开的名称“users”以及嵌入式Mongo的一些配置。我们在这里应该注意,在application.yml文件中配置最好从Git存储库中的Config Server中检索所有微服务。我们在这里有一个小实现,所以我们在这个服务中配置只是为了我们的例子。

如果我们运行它,我们可以从Eureka 网址:http:// localhost:8761看到所有服务都已启动并被检测到。

让我们创建一个数据类User来映射MongoDB中的条目:

@Document data class User(@Id val id: String?, val name: String)

之后,我们可以从Spring Data JPA for User类创建一个UserRepository接口。

interface UserRepository : MongoRepository<User, String> {
}

现在我们可以用一些用户初始化我们的数据库。

@SpringBootApplication
@EnableEurekaClient
class UserServiceApplication(private val userRepository: UserRepository): ApplicationRunner {
  override fun run(args: ApplicationArguments?) {
    createUsers(userRepository)
  }
}
  fun main(args: Array<String>) {
    runApplication<UserServiceApplication>(*args)
  }
  private fun createUsers(userRepository: UserRepository) {
    userRepository.save(User(null, "Peter"))
    userRepository.save(User(null, "John"))
    userRepository.save(User(null, "Sofia"))
    userRepository.save(User(null, "George"))
  }

让我们添加一个UserService接口,该方法将获得所有用户。

interface UserService {
    fun getAllUsers(): List<User>
}

并且UserRepository的服务实现已自动装配。

@Service("userService")
class UserServiceImpl : UserService {
    @Autowired
    lateinit var userRepository: UserRepository
    override fun getAllUsers(): List<User> {
        return userRepository.findAll()
    }
}

最后,我们创建了Controller,它将从UserService获取所有用户并将其名称作为逗号分隔值返回。

@RestController
@RequestMapping("api")
class UserController {
  @Autowired 
  lateinit var userService: UserService
  @GetMapping("/users")
  fun getUsers(): String {
    val users: List<User> = userService.getAllUsers()
    var names: MutableList<String> = users.map { it.name  }.toMutableList()
    return names.joinToString()
  }
}

如果我们现在在http:// localhost:8082 / api / users发出GET请求,我们将得到以下结果:

Peter, John, Sofia, George

现在让我们回到我们在第1部分中创建的数据服务,并添加依赖项:

<dependency>
<groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-feign</artifactId>
     <version>1.4.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>

在Application类中,添加@EnableFeignClients:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
class DataServiceApplication
fun main(args: Array<String>) {
  runApplication<DataServiceApplication>(*args)
}

我们将创建一个DataService,它将用户名从用户服务中检索为逗号分隔值。让我们假设这是一个数据收集器服务,并在实际示例中聚合来自许多微服务的数据。

我们创建了一个名为UserClient的接口,该接口使用Feign Client调用用户服务。

@FeignClient("users")
interface UserClient {
    @RequestMapping(method = arrayOf(RequestMethod.GET), value = "api/users")
    fun getAllUsers(): String
}

我们只需要设置注释@FeignClient和微服务的名称然后声明API的调用。Feign将负责实施。

之后,我们创建DataService,它将使用UserClient。

interface DataService {
    fun getAllUsers(): String
}interface  DataService {
​
@Service("dataService")
class DataServiceImpl : DataService {
    @Autowired 
    lateinit var userClient: UserClient
    override fun getAllUsers(): String {
        return userClient.getAllUsers()
    }
}

最后,我们创建将调用DataService的Controller。

@RestController
@RequestMapping("api/data")
class DataController {
  @Autowired 
  lateinit var dataService: DataService
  @GetMapping("/users")
  fun getAllUsers(): String {
      return dataService.getAllUsers()
  }
}

如果我们现在在http:// localhost:8080 / api / data / users处发出GET请求,我们将再次得到以下结果:

Peter, John, Sofia, George

数据服务使用Feign Client仅使用属性“users”和API URL访问远程服务器,检测用户服务的位置,并在不需要提供进一步信息的情况下获得结果。

希望这篇文章能帮助您开始使用Kotlin的Spring Cloud。还有许多其他Spring Cloud概念,如Zuul,非常有趣,希望将来有机会讨论。

原文标题《AdaBoost Algorithm For Machine Learning》

作者:Efthymios Vafeiadis

译者:February

不代表云加社区观点,更多详情请查看原文链接

原文链接:https://dzone.com/articles/kotlin-microservices-with-spring-cloud-netflix-par-1

原文作者:Efthymios Vafeiadis

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

Android NDk环境配置

概论 NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应...

215100
来自专栏JMCui

浅析 SpringMVC 原理和配置.

一、原理       Spring MVC基于模型-视图-控制器(Model-View-Controller,MVC)模式实现,它能够帮你构建像Spring框架...

40090
来自专栏CodingBlock

Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身

本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8479282.html

13030
来自专栏A周立SpringCloud

Spring Cloud各组件重试总结

最近挺多童鞋问我如何配置Spring Cloud xxx组件的重试。本篇进行一个总结。 Spring Cloud中的重试机制应该说是比较混乱的,不同的版本有一定...

48560
来自专栏Java Web

使用RESTful风格开发Java Web

14230
来自专栏云原生架构实践

Jhipster技术栈定制 - 基于UAA的微服务之间安全调用

3个微服务都是通过Jhipster生成。 工程代码生成完之后,根据上一节启动的组件的实际情况,修改微服务配置文件中Eureka和database相关的配置。

1K30
来自专栏菩提树下的杨过

Spring Security笔记:Hello World

本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(...

20880
来自专栏CodingBlock

Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身

本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8479282.html

11440
来自专栏java学习

使用intellij idea搭建MAVEN+SSM(Spring+SpringMVC+MyBatis)框架

Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-On...

61950
来自专栏CodingBlock

Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身

本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8479282.html 在Android...

29860

扫码关注云+社区

领取腾讯云代金券