栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringCloud-Eureka与生产者消费者

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringCloud-Eureka与生产者消费者

今天继续学习SpringCloud。

上篇我们讲了微服务的概念

这一篇针对如何在Eureka上注册服务,消费者如何消费详细说说

以下代码皆用最简单的代码示例,并非真正的业务代码

学习中用到的学习资料如下:

文章:SpringCloud极简入门

视频:Spring Cloud从入门到实战


Eureka分为两部分

  • Eureka Server,注册中心
  • Eureka Client,所有要进行注册的微服务通过 Eureka Client 连接到 Eureka Server,完成注册。
Eureka Server代码实现
  • 创建父工程,pom.xml

```xml org.springframework.boot spring-boot-starter-parent 2.0.7.RELEASE

org.springframework.boot spring-boot-starter-web

org.springframework.cloud spring-cloud-dependencies Finchley.SR2 pom import ```

  • 在父工程下创建 Module,pom.xml

xml org.springframework.cloud spring-cloud-starter-netflix-eureka-server 2.0.2.RELEASE

  • 创建配置文件 application.yml,添加 Eureka Server 相关配置。

yaml server: port: 8761 eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://localhost:8761/eureka/

属性说明

server.port:当前 Eureka Server 服务端口。

eureka.client.register-with-eureka:是否将当前的 Eureka Server 服务作为客户端进行注册。

eureka.client.fetch-fegistry:是否获取其他 Eureka Server 服务的数据。

eureka.client.service-url.defaultZone:注册中心的访问地址。

  • 创建启动类

```java package com.janeroad;

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class,args); } } ```

注解说明:

@SpringBootApplication:声明该类是 Spring Boot 服务的入口。

@EnableEurekaServer:声明该类是一个 Eureka Server 微服务,提供服务注册和服务发现功能,即注册中心。

打开浏览器,访问 http://localhost:8761,可看到如下界面,注册中心启动成功

服务提供者代码实现

分布式系统架构中的所有微服务都需要在注册中心完成注册才能被发现进而使用,服务提供者和服务消费者是从业务角度来划分的,实际上服务提供者和服务消费者都是通过 Eureka Client 连接到 Eureka Server 完成注册,现在实现一个服务提供者,并且在 Eureka Server 完成注册,大致思路是先通过 Spring Boot 搭建一个微服务应用,再通过 Eureka Client 将其注册到 Eureka Server,创建 Eureka Client 的过程与创建 Eureka Server 十分相似。

  • 创建 Module ,pom.xml

xml org.springframework.cloud spring-cloud-starter-netflix-eureka-client 2.0.2.RELEASE

  • 创建配置文件 application.yml,添加 Eureka Client 相关配置

yaml server: port: 8010 spring: application: name: provider eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true

属性说明:

spring.application.name:当前服务注册在 Eureka Server 上的名称。

eureka.client.service-url.defaultZone:注册中心的访问地址。

eureka.instance.prefer-ip-address:是否将当前服务的 IP 注册到 Eureka Server。

  • 创建启动类

```java package com.janeroad;

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class,args); } } ```

  • 实体类

```java package com.janeroad.entity;

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;

@Data @AllArgsConstructor @NoArgsConstructor public class Student { private long id; private String name; private int age; } ```

  • Repository

```java package com.janeroad.repository;

import com.janeroad.entity.Student;

import java.util.Collection;

public interface StudentRepository { public Collection findAll(); public Student findById(long id); public void saveOrUpdate(Student student); public void deleteById(long id); } ```

  • RepositoryImpl

```java package com.janeroad.repository.impl;

import com.janeroad.entity.Student; import com.janeroad.repository.StudentRepository; import org.springframework.stereotype.Repository;

import java.util.Collection; import java.util.HashMap; import java.util.Map;

@Repository public class StudentRepositoryImpl implements StudentRepository { private static Map studentMap; static { studentMap = new HashMap<>(); studentMap.put(1L,new Student(1L,"张三",22)); studentMap.put(2L,new Student(2L,"李四",23)); studentMap.put(3L,new Student(3L,"王五",24)); }

@Override
public Collection findAll() {
    return studentMap.values();
}

@Override
public Student findById(long id) {
    return studentMap.get(id);
}

@Override
public void saveOrUpdate(Student student) {
    studentMap.put(student.getId(),student);
}

@Override
public void deleteById(long id) {
    studentMap.remove(id);
}

} ```

  • Handler

```java package com.janeroad.controller;

import com.janeroad.entity.Student; import com.janeroad.repository.StudentRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@RestController @RequestMapping("/student") public class StudentHandler { @Autowired private StudentRepository studentRepository; @Value("${server.port}") private String port; @GetMapping("/findAll") public Collection findAll(){ return studentRepository.findAll(); }

@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") long id){
    return studentRepository.findById(id);
}

@PostMapping("/save")
public void save(@RequestBody Student student){
    studentRepository.saveOrUpdate(student);
}

@PutMapping("/update")
public void update(@RequestBody Student student){
    studentRepository.saveOrUpdate(student);
}

@DeleteMapping("/deleteById/{id}")
public void deleteById(@PathVariable("id") long id){
    studentRepository.deleteById(id);
}

@GetMapping("/index")
public String index(){
    return "当前端口:"+this.port;
}

} ```

打开浏览器,访问 http://localhost:8761,看到如下界面。

运行eurekaclient启动类效果

RestTemplate 的使用
  • 什么是REST

REST是当前比较流行的一种互联网软件架构模型,通过统一的规范完成不同终端的数据访问和交互,REST是一个词组的缩写,全称为代表性状态转移,翻译成中文的意思是资源表现层状态转化。

特色

1、URL传参更加简洁,如下所示:

  • 非RESTful的URL:http://...../queryUserById?id=1
  • RESTful的URL:http://..../queryUserById/1

2、完成不同终端之间的资源共享,RESTful提供了一套规范,不同终端之间只需要遵守该规范,就可以实现数据交互。

Restful具体就是就是一种表现形式,HTTP协议的中部请求类型(GET,POST,PUT,DELETE)分别表示常规操作,即CRUD:

  • 获取获取资源
  • POST创造创造资源
  • 放置修改属性
  • DELETE用作删除资源

什么是RestTemplate

RestTemplate是Spring框架提供的基于REST的服务组件,通过对HTTP请求和响应进行了封装,提供了很多访问远程REST服务的方法,可简化代码开发。

  • 如何使用 RestTemplate?

1、创建 Maven 工程,pom.xml。

2、创建实体类

```java package com.janeroad.entity;

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;

@Data @AllArgsConstructor @NoArgsConstructor public class Student { private long id; private String name; private int age; } ```

3、Handler

```java package com.janeroad.controller;

import com.janeroad.entity.Student; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate;

import java.util.Collection;

@RestController @RequestMapping("/rest") public class RestHandler { @Autowired private RestTemplate restTemplate; @GetMapping("/findAll") public Collection findAll(){ return restTemplate.getForEntity("http://localhost:8010/student/findAll",Collection.class).getBody(); }

@GetMapping("/findAll2")
public Collection findAll2(){
    return restTemplate.getForObject("http://localhost:8010/student/findAll",Collection.class);
}

@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") long id){
    return restTemplate.getForEntity("http://localhost:8010/student/findById/{id}",Student.class,id).getBody();
}

@GetMapping("/findById2/{id}")
public Student findById2(@PathVariable("id") long id){
    return restTemplate.getForObject("http://localhost:8010/student/findById/{id}",Student.class,id);
}

@PostMapping("/save")
public void save(@RequestBody Student student){
    restTemplate.postForEntity("http://localhost:8010/student/save",student,null).getBody();
}

@PostMapping("/save2")
public void save2(@RequestBody Student student){
    restTemplate.postForObject("http://localhost:8010/student/save",student,null);
}

@PutMapping("/update")
public void update(@RequestBody Student student){
    restTemplate.put("http://localhost:8010/student/update",student);
}

@DeleteMapping("/deleteById/{id}")
public void deleteById(@PathVariable("id") long id){
    restTemplate.delete("http://localhost:8010/student/deleteById/{id}",id);
}

} ```

4、启动类

```java package com.janeroad;

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;

@SpringBootApplication public class RestTemplateApplication { public static void main(String[] args) { SpringApplication.run(RestTemplateApplication.class,args); } @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } } ```

RestTemplate不是一个微服务,就是一个单纯的Spring Boot应用,但是可以调用eurekaclient服务提供者的方法

RestTemplate启动效果

服务消费者代码实现

实现一个用户的消费者,调用提供者的相关接口,实现思路是先通过Spring Boot构建一个微服务应用,再通过Eureka Client将其注册到Eureka Server。此时的提供者和消费者从代码的角度看并没有区别,都是Eureka客户端,我们人为地从业务角度对它们进行区分,提供者提供服务,消费者调用服务,具体的实现需要结合RestTemplate来完成,即在服务消费者Consumer中通过RestTemplate来调用服务提供者provider的相关接口。

  • 创建 Maven 工程,pom.xml

xml org.springframework.cloud spring-cloud-starter-netflix-eureka-client 2.0.2.RELEASE

  • 创建配置文件 application.yml

yaml server: port: 8020 spring: application: name: consumer eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true

  • 创建启动类

```java package com.janeroad;

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;

@SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class,args); } @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } } ```

  • Handler

```java package com.janeroad.controller;

import com.janeroad.entity.Student; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate;

import java.util.Collection;

@RestController @RequestMapping("/consumer") public class ConsumerHandler { @Autowired private RestTemplate restTemplate; @GetMapping("/findAll") public Collection findAll(){ return restTemplate.getForEntity("http://localhost:8010/student/findAll",Collection.class).getBody(); }

@GetMapping("/findAll2")
public Collection findAll2(){
    return restTemplate.getForObject("http://localhost:8010/student/findAll",Collection.class);
}

@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") long id){
    return restTemplate.getForEntity("http://localhost:8010/student/findById/{id}",Student.class,id).getBody();
}

@GetMapping("/findById2/{id}")
public Student findById2(@PathVariable("id") long id){
    return restTemplate.getForObject("http://localhost:8010/student/findById/{id}",Student.class,id);
}

@PostMapping("/save")
public void save(@RequestBody Student student){
    restTemplate.postForEntity("http://localhost:8010/student/save",student,null).getBody();
}

@PostMapping("/save2")
public void save2(@RequestBody Student student){
    restTemplate.postForObject("http://localhost:8010/student/save",student,null);
}

@PutMapping("/update")
public void update(@RequestBody Student student){
    restTemplate.put("http://localhost:8010/student/update",student);
}

@DeleteMapping("/deleteById/{id}")
public void deleteById(@PathVariable("id") long id){
    restTemplate.delete("http://localhost:8010/student/deleteById/{id}",id);
}

} ```

consumer实际上是一个服务消费者,间接地去访问数据

consumer启动效果

其他增删改查的功能展示这里就省略了,可以用postman去测试

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/434669.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号