Spring Cloud【Finchley】-01服务提供者与服务消费者

简介: Spring Cloud【Finchley】-01服务提供者与服务消费者

20190806093230928.jpg

Spring Cloud总览



20190112144526978.png


概述


服务提供者: 服务的被调用发,为其他服务提供服务的服务

服务消费者: 服务的调用方,即依赖其他服务的服务


示例

场景描述


20181201221102779.png

围绕该场景,需要两个微服务

  • 用户微服务,作为服务提供者为电影微服务提供服务
  • 电影微服务,作为消费者调用用户微服务提供的服务


用户微服务

Spring Boot 2.1.1

Spring Data JPA

H2

lombok简化编码


新建Spring Boot服务


20181201221413954.png


20181201221436479.png


项目结构

2018120122173672.png

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.artisan</groupId>
  <artifactId>micorservice-simple-provider-user</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>micorservice-simple-provider-user</name>
  <description>Demo project for Spring Cloud</description>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.4</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>


用户库表

简单起见,我们使用H2数据库


20181201222027323.png

schema.sql

drop table user if exists;
create table user(
  id bigint generated by default as identity,
  username varchar(40),
  name varchar(20),
  age int(3),
  balance decimal(10,2), 
  primary key(id)
);


data.sql

insert into user(id,username, name, age, balance) values(1,'user1', '张三', 20, 100.00);
insert into user(id,username, name, age, balance) values(2,'user2', '李四', 20, 100.00);
insert into user(id,username, name, age, balance) values(3,'user3', '王五', 20, 100.00);
insert into user(id,username, name, age, balance) values(4,'user4', '马六', 20, 100.00);


Model

为了简化代码,使用了lombok的@Data注解

package com.artisan.microservice.model;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Data;
@Entity
@Data
public class User implements Serializable {
  private static final long serialVersionUID = 226695758444267342L;
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id ;
  @Column
  private String username;
  @Column
  private String name;
  @Column
  private Integer age;
  @Column
  private BigDecimal balance;
}


Dao层

使用Spring Data JPA操作数据库

package com.artisan.microservice.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.artisan.microservice.model.User;
@Repository
public interface UserRepository extends JpaRepository<User,Long>{
}



Service

按道理都应该有Service层,这里demo比较简单,省略也可以,直接在Controller层调用Dao层


Controller 暴露Rest API

package com.artisan.microservice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.artisan.microservice.model.User;
import com.artisan.microservice.repository.UserRepository;
@RestController
public class UserController {
  @Autowired
  private UserRepository userRepository;
  @GetMapping("/user/{id}")
  public User findById(@PathVariable Long id) {
    User user = new User();
      user.setId(id);
      User user2 = new User();
      user2.setName("no this user");
      // 我们使用的spring boot2.1.1版本中关联使用的spring data jpa不再支持findone(id)方法,改成如下写法
      return userRepository.findOne(Example.of(user)).orElse(user2); 
  }
}


配置文件application.yml

server:
  port: 7900
spring:
  jpa:
    generate-ddl: false
    show-sql: true
    hibernate:
      ddl-auto: none
  datasource:
    platform: h2
    schema: classpath:schema.sql
    data: classpath:data.sql
logging:
  level:
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
    com.artisan: DEBUG



测试

package com.artisan.microservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MicorserviceSimpleProviderUserApplication {
  public static void main(String[] args) {
    SpringApplication.run(MicorserviceSimpleProviderUserApplication.class, args);
  }
}


右键–Run As --Spring Boot App,启动成功后


访问数据库中存在的用户

http://localhost:7900/user/1

{"id":1,"username":"user1","name":"张三","age":20,"balance":100.00}

http://localhost:7900/user/2

{"id":2,"username":"user2","name":"李四","age":20,"balance":100.00}

http://localhost:7900/user/3

{"id":3,"username":"user3","name":"王五","age":20,"balance":100.00}

http://localhost:7900/user/4

{"id":4,"username":"user4","name":"马六","age":20,"balance":100.00}

访问数据库中不存在的一个用户

http://localhost:7900/user/66

{"id":null,"username":null,"name":"no this user","age":null,"balance":null}


电影微服务

新建Spring Boot服务

如用户微服务,只不过我们这里仅仅作为消费者,仅使用web即可。


项目结构


20181201223831302.png

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.artisan</groupId>
  <artifactId>micorservice-simple-consumer-movie</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>micorservice-simple-consumer-movie</name>
  <description>Demo project for Spring Cloud</description>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <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>
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.4</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>


Controller通过 RestTemplate 调用用户微服务提供的服务

因为仅仅作为服务消费者,所有只要在Controller层调用对应的rest接口即可

package com.artisan.microservice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.artisan.microservice.model.User;
@RestController
public class MovieController {
  @Autowired
  private RestTemplate restTemplate;
  @Value("${user.userServicePath}")
  private String userServicePath;
  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
    return this.restTemplate.getForObject(this.userServicePath + id, User.class);
  }
}


用到了User类,新建个User.java

package com.artisan.microservice.model;
import java.io.Serializable;
import java.math.BigDecimal;
import lombok.Data;
@Data
public class User implements Serializable {
  private static final long serialVersionUID = 8912111288470833198L;
  private Long id;
  private String username;
  private String name;
  private Integer age;
  private BigDecimal balance;
}


启动类入口处,通过@Bean实例化RestTemplate

通过@Bean实例化RestTemplate

package com.artisan.microservice;
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 MicorserviceSimpleConsumerMovieApplication {
  @Bean
  public RestTemplate restTemplate(){
    return new RestTemplate();
  }
  public static void main(String[] args) {
    SpringApplication.run(MicorserviceSimpleConsumerMovieApplication.class, args);
  }
}


配置文件 application.yml

配置端口及用户微服务的地址

server:
  port: 7901
user: 
  userServicePath: http://localhost:7900/user/


测试


启动用户微服务,访问7901

访问数据库中存在的用户

http://localhost:7901/movie/1

{"id":1,"username":"user1","name":"张三","age":20,"balance":100.00}

http://localhost:7901/movie/2

{"id":2,"username":"user2","name":"李四","age":20,"balance":100.00}

http://localhost:7901/movie/3

{"id":3,"username":"user3","name":"王五","age":20,"balance":100.00}


http://localhost:7901/movie/4

{"id":4,"username":"user4","name":"马六","age":20,"balance":100.00}

访问数据库中不存在的一个用户

http://localhost:7901/movie/66

{"id":null,"username":null,"name":"no this user","age":null,"balance":null}


成功调用到了用户微服务对外提供的服务。


示例的缺点


不难发现,虽然我们把用户微服务对外提供的接口地址配置在了配置文件中,然后通过@Value的方式去加载该属性,但是一旦用户微服务修改了地址,电影微服务作为消费者也要修改对应的地址,多了的话,也是很难管理


第二个原因,如果存在多个用户微服务,如何进行负载? nginx固然可以,如果这种服务比较多,依赖nginx, 增加节点还是需要修改nginx配置文件,比较头疼


所以 接下来我们来看下服务发现与服务注册,这里主要说的是Spring Cloud支持比较好的Eureka

相关文章
|
6月前
|
人工智能 自然语言处理 Java
对话即服务:Spring Boot整合MCP让你的CRUD系统秒变AI助手
本文介绍了如何通过Model Context Protocol (MCP) 协议将传统Spring Boot服务改造为支持AI交互的智能系统。MCP作为“万能适配器”,让AI以统一方式与多种服务和数据源交互,降低开发复杂度。文章以图书管理服务为例,详细说明了引入依赖、配置MCP服务器、改造服务方法(注解方式或函数Bean方式)及接口测试的全流程。最终实现用户通过自然语言查询数据库的功能,展示了MCP在简化AI集成、提升系统易用性方面的价值。未来,“对话即服务”有望成为主流开发范式。
4923 7
|
11月前
|
存储 数据可视化 Java
基于MicrometerTracing门面和Zipkin实现集成springcloud2023的服务追踪
Sleuth将会停止维护,Sleuth最新版本也只支持springboot2。作为替代可以使用MicrometerTracing在微服务中作为服务追踪的工具。
470 2
|
7月前
|
网络协议 Java Shell
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
372 7
|
9月前
|
消息中间件 监控 Java
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
135 6
|
9月前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
154 5
|
9月前
|
缓存 监控 Java
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
166 5
|
10月前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
278 3
|
12月前
|
Java API 对象存储
微服务魔法启动!Spring Cloud与Netflix OSS联手,零基础也能创造服务奇迹!
这段内容介绍了如何使用Spring Cloud和Netflix OSS构建微服务架构。首先,基于Spring Boot创建项目并添加Spring Cloud依赖项。接着配置Eureka服务器实现服务发现,然后创建REST控制器作为API入口。为提高服务稳定性,利用Hystrix实现断路器模式。最后,在启动类中启用Eureka客户端功能。此外,还可集成其他Netflix OSS组件以增强系统功能。通过这些步骤,开发者可以更高效地构建稳定且可扩展的微服务系统。
168 1
|
6月前
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
7月前
|
人工智能 SpringCloudAlibaba 自然语言处理
SpringCloud Alibaba AI整合DeepSeek落地AI项目实战
在现代软件开发领域,微服务架构因其灵活性、可扩展性和模块化特性而受到广泛欢迎。微服务架构通过将大型应用程序拆分为多个小型、独立的服务,每个服务运行在其独立的进程中,服务与服务间通过轻量级通信机制(通常是HTTP API)进行通信。这种架构模式有助于提升系统的可维护性、可扩展性和开发效率。
2130 2