微服务的设计原则:
1、单一职责原则 一个微服务只干一件事
2、服务自治原则 每个微服务应该能做到独立开发、测试、部署、维护,不需要其他模块的参与
3、轻量级通讯原则 最好能够通过http请求在服务之间进行互相的调用
4、接口明确原则 微服务之间进行访问、调用都是通过接口的方式进行调用,尽量避免在一个微服务
中包含其他微服务的内容
微服务版本对应关系
使用spring cloud做微服务的大体结构
开发步骤:
创建项目为maven项目,我的jdk版本是jdk1.8,因此需要改动一下maven配置文件,将jdk版本改为jdk1.8,不然建立的项目为jdk1.5版本如图
修改:maven下的setting.xml文件
在200行左右找到如下位置,改为:
复制代码块粘贴进去
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
创建项目:
①创建父工程
②:在父工程导入依赖
<dependencyManagement>
<dependencies>
<!-- spring cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.15</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 引入插件,读取maven项目的配置文件 -->
<build>
<finalName>SpringCloud63</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimiter>$</delimiter>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
③创建公共模块,在父项目名上右键->新建
④在公共模块(SpringCloud63_Commons)中添加公共类Product类
需要提前在pom.xml引入lombok
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
Product类
package com.woniuxy.commons.entity;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
@Data
public class Product implements Serializable{
private static final long serialVersionUID = 1L;
private Integer pid;
private String pname;
private Double price;
private Integer count;
private String detial;
private List<String> images;
private List<String> productType;
}
⑤创建user模块
创建方式和上一样,不过类型选为war包:
点击fish,出现错误是因为项目为war包,需要导入web.xml,点击选择项目,右键,找到 java EE toos,点击Generate Depoyment Descript stub即可
在user模块的pom中导入commons模块
<!-- 引入公共模块 -->
<dependency>
<groupId>com.woniuxy</groupId>
<artifactId>SpringCloud63_Commons</artifactId>
<version>${project.version}</version>
</dependency>
⑥创建商品模块,创建方式与创建用户模块一致
⑦在商品模块的pom中引入以下依赖
<dependencies>
<!-- 引入公共模块 -->
<dependency>
<groupId>com.woniuxy</groupId>
<artifactId>SpringCloud63_Commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId> <!-- 此处不需要指定版本,在父工程有 -->
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<!-- spring boot -->
<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>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
⑧给商品模块添加application.yml文件
server:
port: 8002
spring:
application:
name: springcloud63-product
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/car
username: root
password: 123456
⑨编写mapper、service、handler
mapper
package com.woniuxy.product.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.woniuxy.commons.entity.Product;
@Mapper
public interface ProductMapper {
//查询所有的商品
@Select("select * from product")
@Results({
//主键映射
@Result(id=true,column="pid",property="pid"),
//图片
@Result(column="pid",property="images",many=@Many(select="findImagesByPid")),
//商品类型
@Result(column="pid",property="productType",many=@Many(select="findProductTypeByPid"))
})
public List<Product> all();
//以pid作为条件查询对应的图片
@Select("select name from images where pid = #{pid}")
public List<String> findImagesByPid(int pid);
//以pid作为查询条件,查询所有的类型
@Select("select productType from producttype where pid = #{pid}")
public List<String> findProductTypeByPid(int pid);
//以pid查询商品
@Select("select * from product where pid = #{pid}")
@Results({
//主键映射
@Result(id=true,column="pid",property="pid"),
//图片
@Result(column="pid",property="images",many=@Many(select="findImagesByPid")),
//商品类型
@Result(column="pid",property="productType",many=@Many(select="findProductTypeByPid"))
})
public Product findProductByPid(Integer pid);
//加减库存
@Update("update set count=count+#{count} where pid=#{pid}")
public int changeCount(Product product);
}
service
package com.woniuxy.product.service;
import java.util.List;
import com.woniuxy.commons.entity.Product;
public interface ProductService {
public List<Product> all();
public Product findProductByPid(Integer pid);
}
serviceimpl
package com.woniuxy.product.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.woniuxy.commons.entity.Product;
import com.woniuxy.product.mapper.ProductMapper;
import com.woniuxy.product.service.ProductService;
@Service
public class ProductServiceImpl implements ProductService{
@Autowired
private ProductMapper productMapper;
@Cacheable("all")
@Override
public List<Product> all() {
return productMapper.all();
}
@Cacheable("findProductByPid")
@Override
public Product findProductByPid(Integer pid) {
// TODO Auto-generated method stub
return productMapper.findProductByPid(pid);
}
}
handler
package com.woniuxy.product.handler;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.woniuxy.commons.entity.Product;
import com.woniuxy.product.service.ProductService;
@RestController
@RequestMapping("/product")
public class ProductHandler {
@Autowired
private ProductService productService;
//所有商品
@RequestMapping("/all")
public List<Product> all() {
System.err.println("8002");
return productService.all();
}
@RequestMapping("/findByPid")
public Product findByPid(Integer pid) {
return productService.findProductByPid(pid);
}
}
⑩编写启动类,启动测试 …
结果展示:取得数据
user与product之间使用RestTemplate进行通信
11、在user模块中添加以下依赖 spring boot
<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>
</dependency>
12、在user模块中添加一个配置类,创建restTemplate
package com.woniuxy.user.configuration;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfiguration {
@Bean
@LoadBalanced//加载负载均衡
public RestTemplate cerate() {
return new RestTemplate();
}
}
13、创建handler,指定请求方法,通过resttemplate访问product模块
package com.woniuxy.user.handler;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.woniuxy.commons.entity.Product;
import com.woniuxy.commons.service.FeignProductService;
@RestController
@RequestMapping("/user")
public class UserHandler {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/all")
public List<Product> all() {
//原始地址
//String url = "http://localhost:8002/product/all";
List<Product> products = restTemplate.getForObject(url, List.class);
}
}
14、创建启动类进行测试
package com.woniuxy.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);