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

之前所有代码都在同一个框架的时候,比如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...

创建Dao类UserRepository
Java代码

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

创建Service类UserService
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)当有多个提供者节点的时候,怎么进行负载,基本想法可以在提供者和消费者中间加一个反向代理,但是服务太多的时候不利于管理。

更多参考内容:http://www.roncoo.com/article...


已注销
249 声望48 粉丝