记录一下基础的入门配置,方便学习理解。
推荐原学习文章地址:https://blog.csdn.net/forezp/article/list/6?t=1&
备注:版本号不一样,很多maven依赖的id也不一样,刚开始做测试用的是springboot2.1.3,springcloud是Green,出了很多问题,后来就降低成1.5,edg版本了。
Point:积分系统服务提供者、常规的springboot三层。service层和model层分离出来丢在了point-share,pom直接添加share的依赖
point-share:积分系统公共服务(主要是模型和service层)、分离出单独maven项目供其他服务调用
order:订单系统(添加point-share依赖)消费者
1:eureka服务:
pom:
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.20.RELEASE
com.example
eureka
0.0.1-SNAPSHOT
eureka
Demo project for Spring Boot
1.8
Edgware.SR5
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
启动类:
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
配置文件:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eureka-server
2:Point服务提供者
pom:
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.20.RELEASE
com.example
point
0.0.1-SNAPSHOT
point
Demo project for Spring Boot
1.8
Edgware.SR5
1.3.0
5.1.39
1.0.1
1.2.47
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
${mysql-connector}
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis-spring-boot}
org.projectlombok
lombok
org.slf4j
jcl-over-slf4j
ch.qos.logback
logback-classic
javax.servlet
javax.servlet-api
com.bjj
access
${access.ver}
com.alibaba
druid
1.0.18
com.alibaba
fastjson
${fastjson.version}
com.example
point-share
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
配置文件
server:
port: 8882
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: point-server
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
username: root
password:
driverClassName: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,wall
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#mybatis:
# typeAliasesPackage: com.example.point.model
# mapperLocations: classpath:mapper/*.xml
#开启输出sql日志
logging:
level:
com:
example:
point:
dao: DEBUG
启动类:
@MapperScan("com.example.point.dao")
@EnableEurekaClient
@SpringBootApplication
public class PointApplication {
public static void main(String[] args) {
SpringApplication.run(PointApplication.class, args);
}
}
添加三层:
controller方法
package com.example.point.web;
import com.example.pointshare.feign.PointService;
import com.example.pointshare.model.Point;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
/**
* Created by [email protected] on 2019/5/14
*/
@RestController
@RequestMapping("/point")
@Slf4j
public class PointController {
@Value("${server.port}")
String point;
@Autowired
private PointService pointService;
@RequestMapping(value="/sayHi",method= RequestMethod.GET)
public void sayHi(@RequestParam(value="name") String name){
log.info("point sayHi in name: {},point: {}",name,point);
pointService.sayHi(name);
}
@RequestMapping(value="/findById/{id}",method= RequestMethod.GET)
public Point findById(@PathVariable(value="id") String id){
log.info("point findById in:{} ",id);
Point point=pointService.findById(id);
return point;
}
@RequestMapping(value="/findByIdAndName",method= RequestMethod.POST)
public Point findByIdAndName(@RequestParam(value="id") String id,@RequestParam(value="name") String name){
log.info("point findByIdAndName in:{},{} ",id,name);
Point point=pointService.findByIdAndName(id,name);
return point;
}
@RequestMapping(value="/update",method= RequestMethod.POST)
public void update(@RequestBody Point point){
log.info("point update in:{}",point);
pointService.update(point);
}
}
service实现类(service分离出去了,后续补充):
package com.example.point.service;
import com.example.point.dao.PointDao;
import com.example.pointshare.feign.PointService;
import com.example.pointshare.model.Point;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* Created by [email protected] on 2019/5/14
*/
@Slf4j
@Service
public class PointServiceImpl implements PointService {
@Autowired
PointDao pointDao;
@Override
public void sayHi(String name) {
log.info("point feignImpl sayHi in:{} ",name);
}
@Override
public Point findById(String id) {
return pointDao.findById(id);
}
@Override
public Point findByIdAndName(String id, String name) {
return pointDao.findByIdAndName(id,name);
}
@Override
public void update(Point point) {
point.setUpdateTime(new Date());
pointDao.update(point);
}
}
dao层(直接方便测试就用了注解sql,没有mapper文件):
package com.example.point.dao;
import com.example.pointshare.model.Point;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.jdbc.SQL;
/**
* Created by [email protected] on 2019/5/15
*/
//@Mapper 启动目录已经添加了@MapperScan("com.example.point.dao"),这里可以省略
public interface PointDao {
@Select("select * from t_point where id=#{id}")
//公用同一个resultMap可以添加mapper文件写映射关系
@Results(value = {
@Result(id = true, property = "id", column = "id"),
@Result(property = "userId", column = "user_id"),
@Result(property = "point", column = "point"),
@Result(property = "updateTime", column = "update_time")
})
Point findById(String id);
@Select("select * from t_point where id=#{id} and user_id=#{name}")
@Results(value = {
@Result(id = true, property = "id", column = "id"),
@Result(property = "userId", column = "user_id"),
@Result(property = "point", column = "point"),
@Result(property = "updateTime", column = "update_time")
})
Point findByIdAndName(@Param("id") String id, @Param("name") String name);
@UpdateProvider(type = PointSql.class, method = "update")
void update(Point point);
class PointSql {
public String update(Point point) {
return new SQL() {{
UPDATE("t_point");
//条件写法.
if (point.getPoints() != 0) {
SET("points=points+#{points}");
}
if (point.getUpdateTime() != null) {
SET("update_time=#{updateTime}");
}
WHERE("id=#{id}");
}}.toString();
}
}
}
3:point-share(feign公共API)
pom:
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.21.RELEASE
com.example
point-share
0.0.1-SNAPSHOT
point-share
Demo project for Spring Boot
1.8
Edgware.SR5
1.3.0
5.1.39
1.0.1
1.2.47
org.springframework.cloud
spring-cloud-starter-feign
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
org.slf4j
jcl-over-slf4j
ch.qos.logback
logback-classic
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.apache.maven.plugins
maven-compiler-plugin
service:
package com.example.pointshare.feign;
import com.example.pointshare.model.Point;
import feign.Logger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
/**
* Created by [email protected] on 2019/5/13
*/
@FeignClient(value = "point-server",fallback = PointService.PointFeignHystric.class,configuration = PointService.FeignConfiguration.class)
public interface PointService {
@RequestMapping(value="/point/sayHi",method= RequestMethod.GET)
void sayHi(@RequestParam(value = "name") String name);
@RequestMapping(value="/point/findById/{id}",method= RequestMethod.GET)
Point findById(@PathVariable("id") String id);
@RequestMapping(value="/point/findByIdAndName",method= RequestMethod.POST)//, consumes = MediaType.APPLICATION_JSON_VALUE
Point findByIdAndName(@RequestParam("id") String id, @RequestParam("name") String name);
@RequestMapping(value="/point/update",method= RequestMethod.POST)
//@RequestLine("POST /point/update")
void update(@RequestBody Point point);
@Component
@Slf4j
public class PointFeignHystric implements PointService {
@Override
public void sayHi(String name) {
log.info("sayHi feign error");
}
@Override
public Point findById(String id) {
return null;
}
@Override
public Point findByIdAndName(String id, String name) {
return null;
}
@Override
public void update(Point point) {
}
}
/**
* Created by [email protected] on 2019/5/15
*/
@Configuration
public class FeignConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
}
model:
package com.example.pointshare.model;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
/**
* Created by [email protected] on 2019/5/13
*/
@Data
@ToString
public class Point {
private String id;
private String userId;
private int points;
private Date updateTime;
}
4:order消费者
pom:
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.20.RELEASE
com.example
order
0.0.1-SNAPSHOT
order
Demo project for Spring Boot
1.8
Edgware.SR5
1.3.0
5.1.39
1.0.1
1.2.47
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-feign
mysql
mysql-connector-java
${mysql-connector}
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis-spring-boot}
org.projectlombok
lombok
org.slf4j
jcl-over-slf4j
ch.qos.logback
logback-classic
javax.servlet
javax.servlet-api
com.bjj
access
${access.ver}
com.alibaba
druid
1.0.18
com.alibaba
fastjson
${fastjson.version}
com.example
point-share
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
配置文件:
server:
port: 8881
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: order-server
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
username: root
password:
driverClassName: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,wall
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#日志
logging:
level:
com:
example:
pointshare:
#开启输出feign
feign:
PointService: DEBUG
#开启断路由
feign:
hystrix:
enabled: true
启动类:
package com.example.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@EnableEurekaClient
@EnableFeignClients(basePackages = "com.example.pointshare.feign")
@SpringBootApplication(scanBasePackages = {"com.example"})
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
controller:
package com.example.order.web;
import com.example.order.service.OrderService;
import com.example.pointshare.model.Point;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* Created by [email protected] on 2019/5/14
*/
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping(value="/sayHi",method= RequestMethod.GET)
public void sayHi(@RequestParam(value="name") String name){
log.info("order sayHi in:{} ",name);
orderService.sayHi(name);
}
@RequestMapping(value="/findById/{id}",method= RequestMethod.GET)
public Point findById(@PathVariable(value="id") String id){
log.info("order findById in:{} ",id);
return orderService.findById(id);
}
@RequestMapping(value="/findByIdAndName",method= RequestMethod.POST)
public Point findByIdAndName(@RequestParam(value="id") String id,@RequestParam(value="name") String name){
log.info("order findByIdAndName in:{},{} ",id,name);
return orderService.findByIdAndName(id,name);
}
@RequestMapping(value="/update",method= RequestMethod.POST)
public void update(@RequestBody Point point){
log.info("order update in:{}",point);
orderService.update(point);
}
}
service:
package com.example.order.service;
import com.example.pointshare.model.Point;
/**
* Created by [email protected] on 2019/5/15
*/
public interface OrderService {
void sayHi(String name);
Point findById(String id);
Point findByIdAndName(String id, String name);
void update(Point point);
}
service实现类:
package com.example.order.service.impl;
import com.example.order.service.OrderService;
import com.example.pointshare.feign.PointService;
import com.example.pointshare.model.Point;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by [email protected] on 2019/5/15
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private PointService pointService;
@Override
public void sayHi(String name) {
pointService.sayHi(name);
}
@Override
public Point findById(String id) {
return pointService.findById(id);
}
@Override
public Point findByIdAndName(String id, String name) {
return pointService.findByIdAndName(id,name);
}
@Override
public void update(Point point) {
pointService.update(point);
}
}
代码:
https://github.com/huiyunfei/spring-cloud.git(后续其他中间件测试可能会修改代码,以本文档贴出来的代码为准)
其中point可以启动多端口多实例,feign直接就已经实现了负载均衡。断路由hystric在feignclient里边配置了。包括feign的日志记录。