在微服务中最基本最基本的两个角色是服务提供者与服务消费者。html
以前全部代码都在同一个框架的时候,好比Controller调用Service的,直接注入Service bean便可进行调用了。如今作成微服务以后,那么咱们就须要有一个工程专门提供相应的服务功能,对应的有相应的工程消费这个功能,这就是服务提供者和服务消费者最基本的概念。java
目录大纲:
(1)服务提供者与服务消费者概念
(2)编码思路
(3)服务提供者编码
(4)服务消费者编码
(5)存在问题web
接下来看下具体的内容:
(1)服务提供者与服务消费者概念
服务提供者:服务的被调用方(即,为其余服务提供服务的服务);
服务消费者:服务的调用方(即,依赖其余服务的服务);spring
(2)编码思路
这里咱们使用最基本的方式实现服务提供者和服务消费者。
(1)两个项目,一个服务提供者,一个是服务消费者;
(2)服务提供者从内存数据库H2中查询数据,Controller进行调用获取;
(3)服务消费者调用服务提供者的Controller进行获取数据,而后返回给浏览器。sql
(3)服务提供者编码数据库
新建工程
新建一个提供用户信息的工程,取名为:microservie-provider-userapache
在pom.xml添加依赖包json
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支持: 一、web mvc; 二、restful; 三、jackjson支持; 四、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代码restful
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支持: 一、web mvc; 二、restful; 三、jackjson支持; 四、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)当有多个提供者节点的时候,怎么进行负载,基本想法能够在提供者和消费者中间加一个反向代理,可是服务太多的时候不利于管理。