您现在的位置是:首页 > 文章详情

Spring Cloud服务提供者与服务消费者怎么运作的?

日期:2018-11-29点击:534

微服务中最基本最基本的两个角色是服务提供者与服务消费者。


之前所有代码都在同一个框架的时候,比如Controller调用Service的,直接注入Service bean即可进行调用了。现在做成微服务之后,那么我们就需要有一个工程专门提供相应的服务功能,对应的有相应的工程消费这个功能,这就是服务提供者和服务消费者最基本的概念。


目录大纲:

(1)服务提供者与服务消费者概念
(2)编码思路
(3)服务提供者编码
(4)服务消费者编码
(5)存在问题

 

接下来看下具体的内容:

(1)服务提供者与服务消费者概念

服务提供者:服务的被调用方(即,为其他服务提供服务的服务);

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

 

(2)编码思路

这里我们使用最基本的方式实现服务提供者和服务消费者。

(1)两个项目,一个服务提供者,一个是服务消费者;

(2)服务提供者从内存数据库H2中查询数据,Controller进行调用获取;

(3)服务消费者调用服务提供者的Controller进行获取数据,然后返回给浏览器。

 

(3)服务提供者编码


新建工程

新建一个提供用户信息的工程,取名为:microservie-provider-user


在pom.xml添加依赖包


Xml代码 

<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.kfit</groupId>       <artifactId>ms-provider-user</artifactId>       <version>0.0.1-SNAPSHOT</version>       <packaging>jar</packaging>           <name>ms-provider-user</name>       <url>http://maven.apache.org</url>           <!-- spring boot parent节点,引入这个之后,在下面和spring boot相关的就不需要引入版本了; -->       <parent>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-parent</artifactId>          <version>1.4.1.RELEASE</version>       </parent>           <properties>          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>       </properties>           <dependencies>          <!-- web支持: 1、web mvc; 2、restful; 3、jackjson支持; 4、aop ........ -->          <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-web</artifactId>          </dependency>              <!-- 内存数据库h2 -->          <dependency>              <groupId>com.h2database</groupId>              <artifactId>h2</artifactId>              <scope>runtime</scope>          </dependency>              <!-- spring data jpa -->          <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-data-jpa</artifactId>          </dependency>       </dependencies>   </project>

 

 

在src/main/resources下新建schema.sql添加建表语句

创建了一张User表:

Sql代码  

drop table user if exists;   create table user(       id bigint generated bydefaultas identity,       username varchar(40),       name varchar(20),       age int(3),       balance decimal(10,2),       primarykey(id)   );

在src/main/resources/新建data.sql插入数据

在User表插入几条数据进行测试:

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);

 

创建实体类User

Java代码  

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})   @Entity   public class User implements Serializable{       private static final long serialVersionUID = 1L;       @Id@GeneratedValue       private long id; //主键.       private String username;//用户名.       private String name; //姓名       private int age; //年龄.       private BigDecimal balance;//余额.         }

 

为什么要加@JsonIgnoreProperties呢?

问题在于,使用load方法,您只需要一个代理,而不是真正的对象。代理对象没有已经加载的属性,所以当序列化发生时,没有要序列化的属性。使用get方法,您实际上可以获得真正的对象,这个对象实际上可以被序列化。

具体可以参考文章:https://my.oschina.net/lieefu/blog/680098

 

创建Dao类UserRepository

Java代码  

public interface UserRepository extends JpaRepository<User,Long>{       }

 

创建ServiceUserService

Java代码

@Service   public class UserService {             @Autowired       private UserRepository userRepository;             public User getById(longid){          return userRepository.getOne(id);       }   }


创建Controller类UserController

Java代码  

@RestController   public class UserController {       @Autowired       private UserService userService;             @GetMapping("/user/{id}")       public User getById(@PathVariablelongid){          User user = userService.getById(id);          System.out.println(user);          return user;       }   }

 

在src/main/resources新建application.properties

主要是配置端口号和jpa配置:

Properties代码  

server.port=7900       spring.jpa.generate-ddl=false   spring.jpa.show-sql=true   spring.jpa.hibernate.ddl-auto=none   spring.datasource.platform=h2   spring.datasource.schema=classpath:schema.sql   spring.datasource.data=classpath:data.sql       logging.level.root=INFO   logging.level.org.hibernate=INFO

 

编写启动类

Java代码  

@SpringBootApplication   public class App {       public staticv oid main(String[] args) {          SpringApplication.run(App.class, args);       }   }

 

启动App测试

启动访问:http://127.0.0.1:7900/user/1 可以在浏览器中看到返回信息:

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

到此服务提供者就编写完毕了,这个代码没有什么特别之处,和我们常规代码编写是一样的!。

 

(4)服务消费者编码


新建工程

新建一个服务消费者项目,取名为:microservice-consumer-movice

在pom.xml添加依赖包

Xml代码  

<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.kfit</groupId>     <artifactId>ms-consumer-movice</artifactId>     <version>0.0.1-SNAPSHOT</version>     <packaging>jar</packaging>         <name>ms-consumer-movice</name>     <url>http://maven.apache.org</url>           <!-- spring boot parent节点,引入这个之后,在下面和spring boot相关的就不需要引入版本了; -->       <parent>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-parent</artifactId>          <version>1.5.8.RELEASE</version>       </parent>             <properties>       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>     </properties>         <dependencies>        <!-- web支持: 1、web mvc; 2、restful; 3、jackjson支持; 4、aop ........ -->       <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-web</artifactId>       </dependency>     </dependencies>   </project>

 

新建实体类User

Java代码  

public class User implements Serializable{       private static final longserialVersionUID = 1L;       private long id; //主键.       private String username;//用户名.       private String name; //姓名       private int age; //年龄.       private BigDecimal balance;//余额.         }

 

 

新建Controller类MoviceController

Java代码  

@RestController   public class MoviceController {             @Autowired       private RestTemplate restTemplate;             @GetMapping("/user/{id}")       public User getById(longid){          String url = "http://127.0.0.1:7900/user/"+id;          return restTemplate.getForObject(url, User.class);       }   }

 

 

在src/main/resources新建application.properties

这里只配置了端口号:

server.port=7901

 

新建启动类App.java

Java代码  

@SpringBootApplication   public class App {             @Bean       public RestTemplate restTemplate(){          returnnew RestTemplate();       }             publicstaticvoid main(String[] args) {          SpringApplication.run(App.class, args);       }   }

这里将RestTemplate进行初始化,交给Spring进行管理。


启动测试


启动访问:http://127.0.0.1:7901/user/2 ,返回给浏览器信息:

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

 

(5)存在问题

 该例子简单易理解,但是存在很多的问题,比如:

(1)请求地址(http://127.0.0.1:7900/user/)硬编码了;

(2)当有多个提供者节点的时候,怎么进行负载,基本想法可以在提供者和消费者中间加一个反向代理,但是服务太多的时候不利于管理。

原文链接:https://blog.roncoo.com/article/131479
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章