【分布式】-- 基于Nacos、OpenFeign搭建的微服务抽奖系统后台小案例
1.项目介绍
最近入项目之前要求熟悉一下SpringCloud Nacos微服务基于Feign接口调用并整合Swagger2进行接口文档展示给前端,所以自己按照要求来编写并整合了一套基于SpringCloudAlibaba Nacos、Feign、MyBatis、Swagger2的简单微服务抽奖系统,并结合数据库数据进行数据返回。
框架提供了基础的微服务注册与发现,接口Swagger访问、MyBatis注解实现接口Dao层数据访问,可用于快速搭建一个微服务CRUD基础框架。
抽奖接口主要包含:添加商品接口(包含商品名称和中奖率);抽奖接口,对添加的商品进行抽奖返回中奖商品的功能。
1.1.项目框架搭建
①项目主要结构说明:
- common-api模块:用于存放公共的pojo类、接口返回值枚举类、公共的抽奖函数
- consumer-product7800模块:服务消费方
- provider-product6700模块:服务提供方
②pom.xml依赖说明:
父工程主要pom依赖包:
其中主要的pom依赖有
spring-cloud-alibaba-dependencies
mybatis-spring-boot-starter
lombok
springfox-swagger2
swagger-bootstrap-ui
<!--统一管理jar包版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<springboot.test.version>2.5.0</springboot.test.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>6.0.6</mysql.version>
<druid.version>1.1.16</druid.version>
<mybatis.spring.boot.version>2.1.4</mybatis.spring.boot.version>
<springboot.starter.web>2.4.3</springboot.starter.web>
</properties> <!--子模块继承之后,提供作用:锁定版本+子module不用写groupId和version-->
<dependencyManagement>
<dependencies>
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud alibaba 2.1.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-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>${mysql.version}</version>
</dependency>
<!--web依赖包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.starter.web}</version>
</dependency>
<!--alibaba druid数据库-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--mybatis orm框架-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<!--lombok插件引入-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!--热启动部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>2.1.10.RELEASE</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--测试依赖包引入-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.test.version}</version>
<scope>test</scope>
</dependency>
<!--log4j日志包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--swagger2依赖-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!--swagger第三方ui依赖-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--排除lombok jar在打包编译期间-->
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<!--引入mybatis逆向工程插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/mybatis-generator/generatorConfig.xml
</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
springcloudnacos-provider-product6700
<dependencies>
<!--SpringCloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringBoot整合Web组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--服务注册与发现-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency> <!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--api jar包引入-->
<dependency>
<groupId>com.fengye</groupId>
<artifactId>springcloudnacos-common-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--集合判空工具类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.3</version>
</dependency>
<!--引入Swagger2组件-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--mysql连接驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--引入ui包-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!--swagger第三方ui依赖-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
springcloudnacos-consumer-product7800
<dependencies>
<!--springcloud openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--sentinel熔断限流-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--SpringCloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入自定义的api通用包-->
<dependency>
<groupId>com.fengye</groupId>
<artifactId>springcloudnacos-common-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--SpringBoot整合Web组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入Swagger2组件-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--引入ui包-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!--swagger第三方ui依赖-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.3</version>
</dependency>
</dependencies>
③application.yml配置
重点主要是在服务生产方provider-product6700进行数据库连接、mybatis框架、nacos服务注册相关的配置,具体如下:
server:
port: 6700 spring:
application:
name: nacos-product-provider-6700
cloud:
nacos:
discovery:
server-addr: localhost:8848
#数据库连接池配置
datasource:
username: root
password: admin
#假如时区报错,增加时区配置serverTimezone=UTC
url: jdbc:mysql://localhost:3306/nacosproduct?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver #整合mybatis配置
mybatis:
#config-location: classpath:mybatis/mybatis-config.xml 使用了configuration注解则无需再指定mybatis-config.xml文件
mapper-locations: classpath:mybatis/mapper/*.xml
configuration: #指定mybatis全局配置文件中的相关配置项
map-underscore-to-camel-case: true
type-aliases-package: com.fengye.springcloud.entities #消费者将要去访问的微服务名称
server-url:
nacos-user-service: http://nacos-product-provider
1.2.项目分包结构说明
以一个服务提供方6700来说,就是简单地controller、mapper、service/impl,mapper层使用xml与注解结合的方式都可以。这里不再多说。
而在服务消费方7800来说,主要分为Feign接口调用与Swagger2Config配置类:
2.Swagger2/Feign接口/抽奖接口说明
2.1.Swagger2配置类
①这里主要的就是在项目中会引入Swagger2的依赖包,以及基于国人UI风格的jar包。
<!--引入Swagger2组件-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger第三方ui依赖-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
②编写Swagger2Config配置类:
//将此类交给Spring管理,表示一个配置类
@Configuration
//开启Swagger2
@EnableSwagger2
public class Swagger2Config {
/**
* 创建API应用
* apiInfo() 增加API相关信息
* 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
* 本例采用指定扫描的包路径来定义指定要建立API的目录
*
* @return 返回Swagger的Docket配置Bean实例
*/
@Bean
public Docket createRestApi(Environment environment) {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(true) //enable是否启动swagger,如果为False,则swagger不能在浏览器中访问
.select()
//指定API对象扫描哪个包下面的controller
//参数any():扫描全部; none():都不扫描
//withClassAnnotation:扫描类上的注解,参数是一个注解的反射对象
//withMethodAnnotation:扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.fengye.springcloud"))
//过滤什么路径
.paths(PathSelectors.any())
.build();
} /**
* 创建该API的基本信息(这些基本信息会展现在文档页面中)
* 访问地址:http://项目实际地址/swagger-ui.html
* @return 返回API基本信息
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//Swagger2展示界面的标题(重要)
.title("抽奖接口API文档")
//描述信息(主要)
.description("抽奖接口API文档")
.version("1.0")
//.termsOfServiceUrl("https://swagger.io/docs")
//.license("Apache 2.0")
//.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
//作者信息
.contact(new Contact("fengye", "https://www.cnblogs.com/yif0118/",
"hyfmailsave@163.com"))
.build();
}
}
启动整体的项目之后,访问:http://localhost:7800/doc.html,即可看到具体的UI风格的API文档界面:
2.2.Feign接口请求
Feign的接口请求调用方式主要是基于服务提供方的Controller接口,并在服务消费方编写一个基于Controller接口一样的Service接口层,根据服务名及对应一致的方法名进行调用。
springcloudnacos-provider-product6700
服务提供方Controller接口:
@RestController
@Slf4j
public class ProductController {
@Autowired
private ProductService productService; /**
* 测试Nacos数据接口
*
* @return
*/
@GetMapping(value = "/provider/test")
public CommonResult<Product> getProductTest() {
CommonResult<Product> result = new CommonResult<>();
result.setCode(ResultCodeEnum.SUCCESS.getCode());
result.setData(new Product(1, "iphone12Max", (float) 0.05));
result.setException(null);
result.setMsg("测试数据接口");
result.setUrl(null);
result.setSuccess(true);
return result;
} /**
* 根据id查询商品返回商品接口
*
* @param id
* @return
*/
@GetMapping(value = "/provider/product/{id}")
public CommonResult<Product> getProductById(@PathVariable("id") Integer id) {
Product product = productService.getProductById(id);
if (product != null) {
return new CommonResult<Product>(
ResultCodeEnum.SUCCESS.getCode(),
product,
null,
"根据id查询商品信息成功!商品名称为:" + product,
true,
null);
} return new CommonResult<Product>(
ResultCodeEnum.DATA_NOT_FOUND.getCode(),
null,
null,
"根据id查询商品信息失败!",
false,
null);
} /**
* 获取所有商品
*
* @return
*/
@GetMapping(value = "/provider/getAll")
public CommonResult<List<Product>> getAllProducts() {
List<Product> productList = productService.getProductList();
if (CollectionUtils.isEmpty(productList)) {
return new CommonResult<>(
ResultCodeEnum.DATA_NOT_FOUND.getCode(),
null,
null,
"查询商品列表信息失败!",
false,
null
);
}
return new CommonResult<>(
ResultCodeEnum.SUCCESS.getCode(),
productList,
null,
"查询商品信息成功,所得到的的商品列表为:" + productList,
true,
null
);
} /**
* 添加商品接口:使用Product参数进行JSON数据插入传递参数
*
* @param product
* @return
*/
@PostMapping(value = "/provider/insert")
public Integer insertProduct(@RequestBody Product product) {
return productService.insertProduct(product);
} /**
* 抽奖接口:根据抽奖次数及抽奖商品的概率进行返回抽中的商品
*
* @return
*/
@GetMapping(value = "/provider/luckyDraw")
public CommonResult<Product> luckyDrawProduct() {
List<Product> productList = productService.getProductList();
Product product = LotteryUtil.luckyDraw(productList);
if (product == null) {
return new CommonResult<>(
ResultCodeEnum.PARAMS_NULL.getCode(),
null,
null,
"未抽取到商品,谢谢惠顾!",
false,
null
);
} return new CommonResult<>(
ResultCodeEnum.SUCCESS.getCode(),
product,
null,
"抽奖商品获取成功!抽到的商品名称为:" + product.getProductName(),
true,
null
);
}
}
springcloudnacos-consumer-product7800
服务消费方Servcie Feign接口:
@Component
@FeignClient(value = "nacos-product-provider-6700")
public interface ProductFeignService {
//测试集成Nacos服务接口
@GetMapping(value = "/provider/test")
public CommonResult<Product> getProductTest(); //接口名与url地址与服务生产者接口名称相同
@GetMapping(value = "/provider/product/{id}")
public CommonResult<Product> getProductById(@PathVariable("id") Integer id); //获取所有的商品数据
@GetMapping(value = "/provider/getAll")
public CommonResult<List<Product>> getAllProducts(); //编写一个添加商品接口:包含商品名称和中奖率
@PostMapping(value = "/provider/insert")
public CommonResult<Product> insertProduct(@RequestBody Product product); //编写一个抽奖接口,对添加的商口进行抽奖返回中奖商品
@GetMapping(value = "/provider/luckyDraw")
public CommonResult<Product> luckyDrawProduct();
}
暴露给Swagger2访问的Controller外部接口:
@RestController
@Api(value = "抽奖接口演示",description = "SpringCloud Nacos测试API接口")
public class ProductConsumerController {
@Value("${server.port}")
private String serverPort; @Autowired
private ProductFeignService productFeignService; @ApiOperation(value = "获取所有抽奖商品信息", notes = "获取所有抽奖商品getAllProducts接口")
@GetMapping(value = "/consumer/getAll")
public CommonResult<List<Product>> getAllProducts(){
CommonResult<List<Product>> allProducts = productFeignService.getAllProducts();
String requestUrl = String.format("http://localhost:%s/consumer/getAll", serverPort);
allProducts.setUrl(requestUrl);
return allProducts;
} @ApiOperation(value = "获取商品测试test接口", notes = "test接口")
@GetMapping(value = "/test")
public CommonResult<Product> getProductTest(){
CommonResult<Product> productTest = productFeignService.getProductTest();
String requestUrl = String.format("http://localhost:%s/test", serverPort);
productTest.setUrl(requestUrl);
return productTest;
} @RequestMapping(value = "/consumer/getProductById/{id}")
@ApiOperation(value = "获取对应id商品接口", notes = "根据商品id获取商品信息")
@ApiImplicitParams({
@ApiImplicitParam(paramType="query", name = "id", value = "商品id", required = true, dataType = "Integer"),
})
public CommonResult<Product> getProductById(@PathVariable("id") Integer id){
CommonResult<Product> productRes = productFeignService.getProductById(id);
String requestUrl = String.format("http://localhost:%s/consumer/getProductById/%s", serverPort, id);
productRes.setUrl(requestUrl);
return productRes;
} @PostMapping(value = "/consumer/insert")
@ApiOperation(value = "插入抽奖商品insert接口", notes = "插入商品接口,包含商品信息、商品抽奖概率")
@ApiImplicitParams({
@ApiImplicitParam(paramType="insert", name = "id", value = "商品", required = true, dataType = "Product"),
})
public CommonResult<Product> insertProduct(@RequestBody Product product){
CommonResult<Product> result = productFeignService.insertProduct(product);
String requestUrl = String.format("http://localhost:%s//consumer/insert", serverPort);
result.setUrl(requestUrl);
return result;
} //编写一个抽奖接口,对添加的商口进行抽奖返回中奖商品
@GetMapping(value = "/consumer/luckyDraw")
@ApiOperation(value = "抽奖接口", notes = "抽奖接口,根据概率返回中奖商品")
public CommonResult<Product> luckyDrawProduct(){
CommonResult<Product> commonRes = productFeignService.luckyDrawProduct();
String requestUrl = String.format("http://localhost:%s//consumer/luckyDraw", serverPort);
commonRes.setUrl(requestUrl);
return commonRes;
}
}
2.3.抽奖接口实现
主要用到的抽奖商品类:
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("用户实体类")
public class Product
{
@ApiModelProperty("主键id")
private Integer id; //主键id
@ApiModelProperty("商品名称")
private String productName; //商品名称
@ApiModelProperty("中奖率")
private float winRate; //中奖率 -- 请用户输入小数点后两位
}
公共接口返回值封装类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
private Integer code;
private T data;
private String exception;
private String msg;
private boolean success;
private String url;
}
返回结果枚举类:
@Getter
public enum ResultCodeEnum {
/**
* 返回结果枚举,每个枚举代表着一个状态
*/
SUCCESS(200, "操作成功!"),
ERROR(400, "操作失败!"),
DATA_NOT_FOUND(401, "查询失败!"), PARAMS_NULL(402, "参数不能为空!"), PARAMS_ERROR(405, "参数不合法!"), NOT_LOGIN(403, "当前账号未登录!"); private Integer code;
private String msg; ResultCodeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
主要的抽奖接口实现工具类:
public class LotteryUtil {
/**
* 抽奖设计接口:
* 产生一个随机数,0-5为一等奖商品,6-15为二等奖商品,16-40为三等奖商品,41-100为谢谢惠顾
* 在比较的时候,比较随机数(百分比)与获取商品的概率(百分比)的绝对值,40%以下的才中奖
* 之后计算随机数与中奖概率的绝对值,选择绝对值相差最小的那个为中奖商品
* @param products
* @return
*/
public static Product luckyDraw(List<Product> products) {
//1.产生一个随机数
int probabilityCount = 100;
int randomNum = (int) (Math.random()* probabilityCount);
//2.41-100表示不中奖
if(randomNum > 40){
return null;
} Map<String, Product> map = new HashMap<>();
List<Integer> list = new ArrayList<>();
for (Product product : products) {
int intValue = new BigDecimal(product.getWinRate() * 100).intValue();
int absVal = Math.abs(randomNum - intValue);
list.add(absVal);
}
Integer min = Collections.min(list); for (Product product : products) {
int value = new BigDecimal(product.getWinRate() * 100).intValue();
if(Math.abs(randomNum - value) == min){
return product;
}
}
return null;
}
}
Nacos微服务注册中心:
使用Swagger接口测试返回中奖结果:
抽奖算法需求:抽奖接口按照添加商品接口的名称和中奖率进行抽奖返回中奖商品,中奖率小于等于40%。即有可能按实际概率来抽奖返回不中奖情况。
抽奖算法这里实际的情况应该是按照插入奖品的实际概率0.15来计算真实的抽奖概率,本人这里实现的比较简单,具体的抽奖概率可以
根据实际情况进行优化,也欢迎博友提出相对应的算法建议。
博客示例及相关代码已上传至GitHub:
【分布式】-- 基于Nacos、OpenFeign搭建的微服务抽奖系统后台小案例的更多相关文章
- 【分布式】-- 微服务抽奖系统后台整合MyBatis-Plus
1.整合MyBatis-Plus背景 [分布式]-- 基于Nacos.OpenFeign搭建的微服务抽奖系统后台小案例 本篇是基于上一篇博文微服务抽奖系统后台对持久层MyBatis进行更换,并整合My ...
- Java进阶专题(二十二) 从零开始搭建一个微服务架构系统 (上)
前言 "微服务"一词源于 Martin Fowler的名为 Microservices的,博文,可以在他的官方博客上找到http:/ /martinfowler . com/art ...
- GitHub上最火的SpringCloud微服务商城系统项目,附全套教程
项目介绍 mall-swarm是一套微服务商城系统,采用了 Spring Cloud Greenwich.Spring Boot 2.MyBatis.Docker.Elasticsearch等核心技术 ...
- 基于Golang设计一套微服务架构[转]
article- @嘟嘟噜- May/26/2018 18:35:30 如何基于Golang设计一套微服务架构 微服务(Microservices),这个近几年我们经常听到.那么现在市面上的的微服 ...
- QCon技术干货:个推基于Docker和Kubernetes的微服务实践
2016年伊始,Docker无比兴盛,如今Kubernetes万人瞩目.在这个无比需要创新与速度的时代,由容器.微服务.DevOps构成的云原生席卷整个IT界.在近期举办的QCon全球软件开发大会上, ...
- Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构
Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...
- 【PHP】基于ThinkPHP框架搭建OAuth2.0服务
[PHP]基于ThinkPHP框架搭建OAuth2.0服务 http://leyteris.iteye.com/blog/1483403
- docker微服务部署之:三,搭建Zuul微服务项目
docker微服务部署之:二.搭建文章微服务项目 一.新增demo_eureka模块,并编写代码 右键demo_parent->new->Module->Maven,选择Module ...
- docker微服务部署之:二、搭建文章微服务项目
docker微服务部署之:一,搭建Eureka微服务项目 一.新增demo_article模块,并编写代码 右键demo_parent->new->Module->Maven,选择M ...
随机推荐
- 由一名保安引发的Java设计模式:外观模式
目录 应用场景 外观模式 定义 意图 主要解决问题 何时使用 优缺点 结构 保安的故事 应用场景 使用方要完成一个功能,需要调用提供方的多个接口.方法,调用过程复杂时,我们可以再提供一个高层接口(新的 ...
- Day06_29_Static关键字
Static 关键字 * Static 关键字的用法 - static既可以修饰变量(全局变量和局部变量),又可以修饰方法.static类型的变量称为静态变量,如果不初始化则编译器自动初始化为0 - ...
- Day06_27_多态
多态 最关键一句话: 父类引用 指向(=) 子类对象 Animal a = new Cat(); 什么是多态? 官方说: 接口的多种不同的实现方式即为多态. 多态性是允许你将父对象设置成为一个或更多的 ...
- SAAS云平台搭建札记: (四) AntD For React使用react-router-dom路由接收不同参数页面不刷新的问题
在.net开发员眼里,如果使用MVC,根据路由匹配原则,可以通过各种方式接收参数,比如 /Post/List/1, /Post/List/2,或者 /Post/List?id=1,/Post/List ...
- Django 入门范例
1. Django 介绍 2. Django 环境搭建 3. 模型(Model) 4. 站点管理 5. 视图(View) 6. 模板(Template) 1. Django 介绍 MVC 模型 大部分 ...
- 前后端分离中的无痛刷新token机制
今天我们来说一说前后端分离中的无痛刷新token机制 博主先来分享一波福利,最近挖到的宝藏,刚开始学Java的同学看 https://www.bilibili.com/video/BV1Rx41187 ...
- Ribbon、Feign和OpenFeign的区别
Spring Cloud 微服务架构学习记录与示例 Ribbon Ribbon 是 Netflix开源的基于HTTP和TCP等协议负载均衡组件 Ribbon 可以用来做客户端负载均衡,调用注册中心的服 ...
- C/C++ 介绍的PE文件遍历工具
在前面的笔记中,我总结了Pe结构的一些结构含义,并手动编写了几段PE结构遍历代码,这里我直接把之前的C语言代码进行了封装,形成了一个命令行版的PE文件查看工具,该工具只有20kb,但却可以遍历出大部分 ...
- 使用BurpSuite抓取HTTPS网站的数据包
昨天面试,技术官问到了我如何使用BurpSuite抓取https网站的数据包,一时间没能回答上来(尴尬!).因为以前https网站的数据包我都是用Fiddler抓取的,Fiddlert自动帮我们配置好 ...
- php isset()与empty()的使用
PHP isset函数作用 isset函数是检测变量是否设置. 格式:bool isset( mixed var [, mixed var [, ...]] ) 返回值: 若变量不存在则返回FALSE ...