前言
在昨天的基础上新增了功能
当访问广告服务时会自动将频次加1,当大于等于规定的频次返回失败页面,还有定时任务,并且使用了SpringCloud分布式的操作
话不多说,直接上代码
redis_filter(服务提供者)
项目结构
这个就是昨天的代码改的
改动的代码
AdShowController
@RestController
public class AdShowController {
@Autowired
private RedisFilterService filterService;
@RequestMapping("/show/{uid}/{aid}")
public String show(@PathVariable("uid") String uid,
@PathVariable("aid") String aid) {
if (filterService.incr(uid, aid) == 2) {
return "超过次数不进行调用";
}
return "调用了广告服务接口,频次加1";
}
}
添加定时任务
@Service
public class ScheduleTask {
@Autowired
private RedisFilterService redisFilterService;
//每分钟执行,从数据库中获取用户,广告和频次信息
@Scheduled(cron = "0 0/1 * * * ?")
public void mExecute(){
redisFilterService.setData();
}
//每天12点执行
@Scheduled(cron = "0 0 12 * * ?")
public void dExecute(){
redisFilterService.setData2();
}
}
service层
@Service
public class RedisFilterServiceImpl implements RedisFilterService {
@Autowired
private AdUserService adUserService;
@Resource(name = "user_test")
private RedisTemplate<String, Map<String,String>> redisTemplate;
@Resource
private RedisTemplate<String,String> redisTemplate1;
//将数据库数据加入到redis缓存中
//这里采用本地caffeine缓存,因为用户和广告数据不会经常变
@Override
public void setData(){
for (int i =0;i<adUserService.findAll().size();i++){
Map<String,String> results = new HashMap<>();
results.put(adUserService.findAll().get(i).getUid(),AdShowTimes.AD_LIMIT_TIMES);
redisTemplate.opsForHash().putAll(adUserService.findAll().get(i).getAid(),results);
//设置过期时间
redisTemplate.expire(adUserService.findAll().get(i).getAid(),59,TimeUnit.SECONDS);
}
}
//uid_aid为key,times为value,放入redis缓存中
//重置操作也加入定时任务中,每天清零
@Override
public void setData2(){
for (int i=0;i<adUserService.findAll().size();i++){
redisTemplate1.opsForValue().set(adUserService.findAll().get(i).getUid()+"_"+adUserService.findAll().get(i).getAid()
, "0");
}
}
@Override
//判断是否需要加一
public int incr(String uid, String aid) {
if (Integer.parseInt(Objects.requireNonNull(redisTemplate1.opsForValue().get(uid + "_" + aid)))<10) {
redisTemplate1.opsForValue().increment(uid + "_" + aid);
}else {
notIncr();
return 2;
}
return 3;
}
public void notIncr() {
System.out.println("超过限制不进行调用");
}
}
配置文件
spring:
application:
name: redis-filter-service
redis:
host: 127.0.0.1
port: 6379
database: 0
datasource:
url: jdbc:mysql://localhost:3306/ad_user_time
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
server:
port: 8900
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
启动类
package com.xfgg.demo;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@MapperScan("com.xfgg.demo.dao")
@EnableDiscoveryClient
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
registry_server(注册中心)
这个太ez了
导入依赖,启动类添加注解,修改配置
配置文件
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
instance:
prefer-ip-address: true
hostname: ${spring.cloud.client.ip-address}
#服务注册时,注册名是ip名:应用名:应用端口名
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
client:
register-with-eureka: false
fetch-registry: false
service-url:
#eureka默认地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enable-self-preservation: false
consumer_redis_filter(服务消费者)
项目结构
feignapi
@FeignClient(value = "redis-filter-service",fallback = FeignApiFallBack.class)
public interface FeignApi {
@RequestMapping("/show/{uid}/{aid}")
String show(@PathVariable("uid") String uid,
@PathVariable("aid") String aid);
}
feignapifallback
@Component
public class FeignApiFallBack implements FeignApi{
@Override
public String show(String uid, String aid) {
return "failed";
}
}
redisfiltercontroller
@RestController
public class RedisFilterController {
@Qualifier("com.xfgg.demo.feign.FeignApi")
@Autowired
private FeignApi feignApi;
@RequestMapping("/show/{uid}/{aid}")
String show(@PathVariable("uid") String uid,
@PathVariable("aid") String aid){
return feignApi.show(uid, aid);
}
}
配置文件
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
server:
port: 8700
spring:
application:
name: consumer_redis_filter
启动类
package com.xfgg.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
明天在代码中添加hystrix和dashborad监控表盘,巩固自己学习的springcloud