在微服務中最基本最基本的兩個角色是服務提供者與服務消費者。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)當有多個提供者節點的時候,怎麼進行負載,基本想法能夠在提供者和消費者中間加一個反向代理,可是服務太多的時候不利於管理。