mirror of
https://github.com/qiurunze123/miaosha.git
synced 2023-11-19 22:41:03 +08:00
lua+redis
This commit is contained in:
parent
42d4bb2bd0
commit
0f92dcce51
|
@ -82,7 +82,7 @@
|
|||
| 028 |项目进行dubbo + zk 改造 (已完成dubbo嵌入--springboot 与dubbo结合xml版本)?|[解决思路](/docs/code-solve.md) |
|
||||
| 029 |dubbo客户端 dubbo-admin管理平台 搭建安装|[解决思路](/docs/dubbo-admin.md) |
|
||||
| 030 |如何利用dubbo 的mock 来进行服务降级本地伪装 ?? (有更好的方式进群@我)|[解决思路](/docs/dubbo-zk.md) |
|
||||
| 027 |*** 如何利用lua + redis 取代 nigix + lua 脚本进行分布式限流 ? *** |[解决思路](/docs/redis-good.md) |
|
||||
| 027 |*** 如何利用lua + redis 取代 nigix + lua 脚本进行分布式限流 (请看miaosha-2version) ? *** |[解决思路](/docs/redis-good.md) |
|
||||
|
||||
|
||||
#### [分布式系统发展历程(已更新)](/docs/fenbushi.md)
|
||||
|
|
|
@ -8,6 +8,7 @@ public class AbstractResult {
|
|||
private int code;
|
||||
private String message;
|
||||
|
||||
AbstractResult() {}
|
||||
protected AbstractResult(ResultStatus status, String message) {
|
||||
this.code = status.getCode();
|
||||
this.status = status;
|
||||
|
|
|
@ -10,6 +10,8 @@ public class ResultGeekQ<T> extends AbstractResult implements Serializable {
|
|||
private T data;
|
||||
private Integer count;
|
||||
|
||||
protected ResultGeekQ() {
|
||||
}
|
||||
protected ResultGeekQ(ResultStatus status, String message) {
|
||||
super(status, message);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.geekq.miasha.vo;
|
||||
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.miasha.entity.MiaoshaUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
@ -14,7 +15,7 @@ import lombok.Setter;
|
|||
public class GoodsDetailVo {
|
||||
private int miaoshaStatus = 0;
|
||||
private int remainSeconds = 0;
|
||||
private GoodsVo goods ;
|
||||
private GoodsVoOrder goods ;
|
||||
private MiaoshaUser user;
|
||||
|
||||
}
|
||||
|
|
|
@ -35,5 +35,12 @@
|
|||
|
||||
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -16,6 +16,6 @@ public interface MiaoShaUserMapper {
|
|||
|
||||
public void insertMiaoShaUser(MiaoshaUser miaoshaUser);
|
||||
|
||||
public int getCountByUserName(@Param("userName")String userName , @Param("userType")int userType);
|
||||
public int getCountByUserName(@Param("userName") String userName, @Param("userType") int userType);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
package com.geekq.miaosha.rabbitmq;
|
||||
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.api.utils.AbstractResultOrder;
|
||||
import com.geekq.api.utils.ResultGeekQOrder;
|
||||
import com.geekq.miaosha.redis.RedisService;
|
||||
import com.geekq.miaosha.service.GoodsService;
|
||||
import com.geekq.miaosha.service.MiaoShaMessageService;
|
||||
import com.geekq.miaosha.service.MiaoshaService;
|
||||
import com.geekq.miaosha.service.OrderService;
|
||||
import com.geekq.miasha.entity.MiaoshaOrder;
|
||||
import com.geekq.miasha.entity.MiaoshaUser;
|
||||
import com.geekq.miasha.vo.GoodsVo;
|
||||
import com.geekq.miasha.vo.MiaoShaMessageVo;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.geekq.miasha.enums.enums.ResultStatus;
|
||||
import com.geekq.miasha.exception.GlobleException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Service
|
||||
public class MQReceiver {
|
||||
|
||||
|
@ -36,6 +34,9 @@ public class MQReceiver {
|
|||
@Autowired
|
||||
MiaoshaService miaoshaService;
|
||||
|
||||
@Autowired
|
||||
private com.geekq.api.service.GoodsService goodsServiceRpc;
|
||||
|
||||
// @Autowired
|
||||
// MiaoShaMessageService messageService ;
|
||||
|
||||
|
@ -46,7 +47,13 @@ public class MQReceiver {
|
|||
MiaoshaUser user = mm.getUser();
|
||||
long goodsId = mm.getGoodsId();
|
||||
|
||||
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
||||
// GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
||||
ResultGeekQOrder<GoodsVoOrder> goodsVoOrderResultGeekQOrder = goodsServiceRpc.getGoodsVoByGoodsId(goodsId);
|
||||
if(!AbstractResultOrder.isSuccess(goodsVoOrderResultGeekQOrder)){
|
||||
throw new GlobleException(ResultStatus.SESSION_ERROR);
|
||||
}
|
||||
|
||||
GoodsVoOrder goods= goodsVoOrderResultGeekQOrder.getData();
|
||||
int stock = goods.getStockCount();
|
||||
if(stock <= 0) {
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package com.geekq.miaosha.redis.redismanager;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class RedisLimitRateWithLUA {
|
||||
|
||||
public static void main(String[] args) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
latch.await();
|
||||
System.out.println("请求是否被执行:"+accquire());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public static boolean accquire() throws IOException, URISyntaxException {
|
||||
Jedis jedis = new Jedis("39.107.245.253");
|
||||
|
||||
String lua =
|
||||
"local key = KEYS[1] " +
|
||||
" local limit = tonumber(ARGV[1]) " +
|
||||
" local current = tonumber(redis.call('get', key) or '0')" +
|
||||
" if current + 1 > limit " +
|
||||
" then return 0 " +
|
||||
" else "+
|
||||
" redis.call('INCRBY', key,'1')" +
|
||||
" redis.call('expire', key,'2') " +
|
||||
" end return 1 ";
|
||||
|
||||
String key = "ip:" + System.currentTimeMillis()/1000; // 当前秒
|
||||
String limit = "3"; // 最大限制
|
||||
List<String> keys = new ArrayList<String>();
|
||||
keys.add(key);
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add(limit);
|
||||
jedis.auth("youxin11");
|
||||
String luaScript = jedis.scriptLoad(lua);
|
||||
Long result = (Long)jedis.evalsha(luaScript, keys, args);
|
||||
return result == 1;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import redis.clients.jedis.Jedis;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static redis.clients.jedis.Protocol.Command.INCRBY;
|
||||
|
||||
/**
|
||||
* lua脚本使用
|
||||
*/
|
||||
|
@ -92,4 +94,37 @@ public class RedisLua {
|
|||
logger.error("统计访问次数失败!!!",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void currentlimitMinute() {
|
||||
|
||||
Jedis jedis = null;
|
||||
try {
|
||||
jedis = RedisManager.getJedis();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String lua =
|
||||
"local key = KEYS[1] " +
|
||||
"local limit = tonumber(ARGV[1]) " +
|
||||
"local current = tonumber(redis.call('get', key) or '0') " +
|
||||
"if current + 1 > limit then return 0 " +
|
||||
"else redis.call('INCRBY', key,'1')" +
|
||||
" redis.call('expire', key,'2') " +
|
||||
"end return 1";
|
||||
|
||||
List<String> keys = new ArrayList<String>();
|
||||
keys.add("ip:limit:127.0.0.1");
|
||||
List<String> argves = new ArrayList<String>();
|
||||
argves.add("6000");
|
||||
argves.add("5");
|
||||
jedis.auth("xxxx");
|
||||
|
||||
// Object evalSha = jedis.evalsha(lua);
|
||||
String luaScript = jedis.scriptLoad(lua);
|
||||
System.out.println(luaScript);
|
||||
Object object = jedis.evalsha(luaScript, keys, argves);
|
||||
System.out.println(object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
local key = KEYS[1] --限流KEY(一秒一个)
|
||||
local limit = tonumber(ARGV[1]) --限流大小
|
||||
local current = tonumber(redis.call('get', key) or "0")
|
||||
if current + 1 > limit then --如果超出限流大小
|
||||
return 0
|
||||
else --请求数+1,并设置2秒过期
|
||||
redis.call("INCRBY", key,"1")
|
||||
redis.call("expire", key,"2")
|
||||
end
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
-- ip限流
|
||||
|
||||
|
||||
local key = "rate.limit:" .. KEYS[1]
|
||||
local limit = tonumber(ARGV[1])
|
||||
local expire_time = ARGV[2]
|
||||
|
||||
local is_exists = redis.call("EXISTS", key)
|
||||
if is_exists == 1 then
|
||||
if redis.call("INCR", key) > limit then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
end
|
||||
else
|
||||
redis.call("SET", key, 1)
|
||||
redis.call("EXPIRE", key, expire_time)
|
||||
return 1
|
||||
end
|
|
@ -1,5 +1,7 @@
|
|||
package com.geekq.miaosha.service;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.miaosha.redis.MiaoshaKey;
|
||||
import com.geekq.miaosha.redis.RedisService;
|
||||
import com.geekq.miasha.entity.MiaoshaOrder;
|
||||
|
@ -29,10 +31,14 @@ public class MiaoshaService {
|
|||
@Autowired
|
||||
RedisService redisService;
|
||||
|
||||
@Reference(version = "${demo.service.version}",retries = 3,timeout = 6000)
|
||||
private com.geekq.api.service.GoodsService goodsServiceRpc;
|
||||
|
||||
@Transactional
|
||||
public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {
|
||||
public OrderInfo miaosha(MiaoshaUser user, GoodsVoOrder goods) {
|
||||
//减库存 下订单 写入秒杀订单
|
||||
boolean success = goodsService.reduceStock(goods);
|
||||
// boolean success = goodsService.reduceStock(goods);
|
||||
boolean success =goodsServiceRpc.reduceStock(goods);
|
||||
if(success){
|
||||
return orderService.createOrder(user,goods) ;
|
||||
}else {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.geekq.miaosha.service;
|
||||
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.miaosha.mapper.OrderMapper;
|
||||
import com.geekq.miaosha.redis.OrderKey;
|
||||
import com.geekq.miaosha.redis.RedisService;
|
||||
|
@ -37,7 +38,7 @@ public class OrderService {
|
|||
}
|
||||
|
||||
@Transactional
|
||||
public OrderInfo createOrder(MiaoshaUser user, GoodsVo goods) {
|
||||
public OrderInfo createOrder(MiaoshaUser user, GoodsVoOrder goods) {
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
orderInfo.setCreateDate(new Date());
|
||||
orderInfo.setDeliveryAddrId(0L);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
local key = KEYS[1] --限流KEY(一秒一个)
|
||||
local limit = tonumber(ARGV[1]) --限流大小
|
||||
local current = tonumber(redis.call('get', key) or "0")
|
||||
if current + 1 > limit then --如果超出限流大小
|
||||
return 0
|
||||
else --请求数+1,并设置2秒过期
|
||||
redis.call("INCRBY", key,"1")
|
||||
redis.call("expire", key,"2")
|
||||
end
|
||||
return 1
|
|
@ -1,16 +1,19 @@
|
|||
package com.geekq.miaosha;
|
||||
|
||||
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
|
||||
@EnableDubbo
|
||||
@ImportResource(value={"classpath:consumer.xml"})
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.geekq.miaosha.mapper")
|
||||
public class GeekQMainApplication {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
|
||||
// Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://localhost:2181"));
|
||||
// registry.register(URL.valueOf("override://0.0.0.0/com.geekq.api.service.GoodsService?category=configurators&dynamic=false&application=dubbo-consumer2.0&mock=fail:return+444"));
|
||||
SpringApplication.run(GeekQMainApplication.class, args);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package com.geekq.miaosha.controller;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.api.utils.AbstractResultOrder;
|
||||
import com.geekq.api.utils.ResultGeekQOrder;
|
||||
import com.geekq.miaosha.interceptor.RequireLogin;
|
||||
import com.geekq.miaosha.redis.GoodsKey;
|
||||
import com.geekq.miaosha.redis.RedisService;
|
||||
import com.geekq.miaosha.service.GoodsService;
|
||||
import com.geekq.miaosha.service.MiaoShaUserService;
|
||||
import com.geekq.miasha.entity.MiaoshaUser;
|
||||
import com.geekq.miasha.enums.enums.ResultStatus;
|
||||
import com.geekq.miasha.enums.resultbean.ResultGeekQ;
|
||||
import com.geekq.miasha.exception.GlobleException;
|
||||
import com.geekq.miasha.vo.GoodsDetailVo;
|
||||
import com.geekq.miasha.vo.GoodsVo;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -40,7 +45,7 @@ public class GoodsController extends BaseController {
|
|||
@Autowired
|
||||
private GoodsService goodsService;
|
||||
|
||||
@Reference(version = "${demo.service.version}")
|
||||
@Autowired
|
||||
private com.geekq.api.service.GoodsService goodsServiceRpc;
|
||||
|
||||
@Autowired
|
||||
|
@ -54,12 +59,19 @@ public class GoodsController extends BaseController {
|
|||
* 5000 * 10
|
||||
* QPS:2884, load:5
|
||||
* */
|
||||
@RequireLogin(seconds = 5, maxCount = 5, needLogin = true)
|
||||
@RequestMapping(value="/to_list", produces="text/html")
|
||||
@ResponseBody
|
||||
public String list(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user) {
|
||||
public String list(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user) {
|
||||
model.addAttribute("user", user);
|
||||
// ResultGeekQ<List<com.geekq.api.entity.GoodsVo>> goodsList1 = goodsServiceRpc.listGoodsVo();
|
||||
List<GoodsVo> goodsList = goodsService.listGoodsVo();
|
||||
|
||||
//订单服务化接口 miaosha-order
|
||||
ResultGeekQOrder<List<GoodsVoOrder>> resultGoods = goodsServiceRpc.listGoodsVo();
|
||||
|
||||
if(!AbstractResultOrder.isSuccess(resultGoods)){
|
||||
throw new GlobleException(ResultStatus.SYSTEM_ERROR);
|
||||
}
|
||||
List<GoodsVoOrder> goodsList = resultGoods.getData();
|
||||
model.addAttribute("goodsList", goodsList);
|
||||
return render(request,response,model,"goods_list", GoodsKey.getGoodsList,"");
|
||||
}
|
||||
|
@ -77,6 +89,13 @@ public class GoodsController extends BaseController {
|
|||
}
|
||||
//手动渲染
|
||||
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
||||
/**
|
||||
* rpc服务化接口
|
||||
*/
|
||||
ResultGeekQOrder<GoodsVoOrder> goodsVoOrderResultGeekQOrder = goodsServiceRpc.getGoodsVoByGoodsId(goodsId);
|
||||
if(!AbstractResultOrder.isSuccess(goodsVoOrderResultGeekQOrder)){
|
||||
throw new GlobleException(ResultStatus.SESSION_ERROR);
|
||||
}
|
||||
model.addAttribute("goods", goods);
|
||||
|
||||
long startAt = goods.getStartDate().getTime();
|
||||
|
@ -126,7 +145,16 @@ public class GoodsController extends BaseController {
|
|||
public ResultGeekQ<GoodsDetailVo> detail(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user,
|
||||
@PathVariable("goodsId")long goodsId) {
|
||||
ResultGeekQ<GoodsDetailVo> result = ResultGeekQ.build();
|
||||
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
||||
|
||||
/**
|
||||
* 服务化rpc接口
|
||||
*/
|
||||
ResultGeekQOrder<GoodsVoOrder> goodsVoOrderResultGeekQOrder = goodsServiceRpc.getGoodsVoByGoodsId(goodsId);
|
||||
if(!AbstractResultOrder.isSuccess(goodsVoOrderResultGeekQOrder)){
|
||||
throw new GlobleException(ResultStatus.SESSION_ERROR);
|
||||
}
|
||||
|
||||
GoodsVoOrder goods = goodsVoOrderResultGeekQOrder.getData();
|
||||
long startAt = goods.getStartDate().getTime();
|
||||
long endAt = goods.getEndDate().getTime();
|
||||
long now = System.currentTimeMillis();
|
||||
|
|
|
@ -30,21 +30,20 @@ public class LoginController {
|
|||
@Autowired
|
||||
private MiaoShaUserService userService;
|
||||
|
||||
@Reference(version = "${demo.service.version}")
|
||||
@Reference(version = "${demo.service.version}",mock = "return null")
|
||||
private DemoService demoService;
|
||||
|
||||
@RequestMapping("/sayHello/{name}")
|
||||
@ResponseBody
|
||||
public String sayHello(@PathVariable("name") String name) {
|
||||
|
||||
return demoService.sayHello(name);
|
||||
@RequestMapping("/sayHello")
|
||||
public String sayHello() throws Exception {
|
||||
return "login222";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@RequestMapping("/to_login")
|
||||
public String tologin(LoginVo loginVo, Model model) {
|
||||
public String tologin(LoginVo loginVo, Model model) {
|
||||
logger.info(loginVo.toString());
|
||||
|
||||
//未完成
|
||||
RedisLua.vistorCount(COUNTLOGIN);
|
||||
String count = RedisLua.getVistorCount(COUNTLOGIN).toString();
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.geekq.miaosha.rabbitmq.MQSender;
|
|||
import com.geekq.miaosha.rabbitmq.MiaoshaMessage;
|
||||
import com.geekq.miaosha.redis.GoodsKey;
|
||||
import com.geekq.miaosha.redis.RedisService;
|
||||
import com.geekq.miaosha.redis.redismanager.RedisLimitRateWithLUA;
|
||||
import com.geekq.miaosha.service.GoodsService;
|
||||
import com.geekq.miaosha.service.MiaoShaUserService;
|
||||
import com.geekq.miaosha.service.MiaoshaService;
|
||||
|
@ -25,7 +26,9 @@ import javax.imageio.ImageIO;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -89,6 +92,19 @@ public class MiaoshaController implements InitializingBean {
|
|||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* 分布式限流
|
||||
*/
|
||||
try {
|
||||
RedisLimitRateWithLUA.accquire();
|
||||
} catch (IOException e) {
|
||||
result.withError(EXCEPTION.getCode(), REPEATE_MIAOSHA.getMessage());
|
||||
return result;
|
||||
} catch (URISyntaxException e) {
|
||||
result.withError(EXCEPTION.getCode(), REPEATE_MIAOSHA.getMessage());
|
||||
return result;
|
||||
}
|
||||
|
||||
//是否已经秒杀到
|
||||
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(Long.valueOf(user.getNickname()), goodsId);
|
||||
if (order != null) {
|
||||
|
|
|
@ -68,18 +68,16 @@ spring.rabbitmq.publisher-confirms=true
|
|||
spring.rabbitmq.listener.direct.acknowledge-mode=manual
|
||||
spring.rabbitmq.listener.simple.acknowledge-mode=manual
|
||||
|
||||
spring.application.name = dubbo-consumer
|
||||
|
||||
server.port = 9091
|
||||
|
||||
dubbo.application.name = dubbo-consumer
|
||||
|
||||
demo.service.version = 1.0.0
|
||||
|
||||
dubbo.protocol.name = dubbo
|
||||
dubbo.protocol.port = 20880
|
||||
|
||||
dubbo.registry.address = zookeeper://localhost:2181
|
||||
|
||||
dubbo.consumer.timeout = 5000
|
||||
#spring.application.name = dubbo-consumer
|
||||
#
|
||||
#dubbo.application.name = dubbo-consumer
|
||||
#demo.service.version = 1.0.0
|
||||
#dubbo.protocol.name = dubbo
|
||||
#dubbo.protocol.port = 20880
|
||||
#dubbo.registry.address = zookeeper://localhost:2181
|
||||
#dubbo.consumer.timeout = 5000
|
||||
#dubbo.consumer.mock= true
|
||||
## maven隔离
|
||||
#spring.profiles.active=dev
|
17
miaosha-2version/miaosha-web/src/main/resources/consumer.xml
Normal file
17
miaosha-2version/miaosha-web/src/main/resources/consumer.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||
|
||||
<!-- 为当前服务提供者取个名字,并且提供给注册中心 -->
|
||||
<dubbo:application name="dubbo-consumer3"></dubbo:application>
|
||||
|
||||
<!-- 注册中心的配置,用于消费者的监听 -->
|
||||
<dubbo:registry protocol="zookeeper" address="localhost:2181"></dubbo:registry>
|
||||
|
||||
<!--<!– 监听服务,通过注册中心去进行查找,查找到后进行服务调用 –>-->
|
||||
<dubbo:reference id="goodsServiceRpc" interface="com.geekq.api.service.GoodsService"
|
||||
retries="3" check="false" init="true" timeout="3000" group="goods2"></dubbo:reference>
|
||||
</beans>
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
|
||||
www.coedq.net
|
||||
|
||||
www.xttblog.com
|
||||
|
||||
*/
|
||||
|
||||
#slider {
|
||||
|
||||
margin: 100px auto;
|
||||
|
||||
width: 300px;
|
||||
|
||||
height: 40px;
|
||||
|
||||
position: relative;
|
||||
|
||||
border-radius: 2px;
|
||||
|
||||
background-color: #dae2d0;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
text-align: center;
|
||||
|
||||
user-select: none;
|
||||
|
||||
-moz-user-select: none;
|
||||
|
||||
-webkit-user-select: none;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#slider_bg {
|
||||
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
|
||||
top: 0;
|
||||
|
||||
height: 100%;
|
||||
|
||||
background-color: #7AC23C;
|
||||
|
||||
z-index: 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#label {
|
||||
|
||||
width: 46px;
|
||||
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
|
||||
top: 0;
|
||||
|
||||
height: 38px;
|
||||
|
||||
line-height: 38px;
|
||||
|
||||
border: 1px solid #cccccc;
|
||||
|
||||
background: #fff;
|
||||
|
||||
z-index: 3;
|
||||
|
||||
cursor: move;
|
||||
|
||||
color: #ff9e77;
|
||||
|
||||
font-size: 16px;
|
||||
|
||||
font-weight: 900;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#labelTip {
|
||||
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
|
||||
height: 100%;
|
||||
|
||||
font-size: 13px;
|
||||
|
||||
font-family: 'Microsoft Yahei', serif;
|
||||
|
||||
color: #787878;
|
||||
|
||||
line-height: 38px;
|
||||
|
||||
text-align: center;
|
||||
|
||||
z-index: 2;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
www.coedq.net
|
||||
|
||||
www.xttblog.com
|
||||
|
||||
*/
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
|
||||
www.coedq.net
|
||||
|
||||
www.xttblog.com
|
||||
|
||||
*/
|
||||
|
||||
#slider {
|
||||
|
||||
margin: 100px auto;
|
||||
|
||||
width: 300px;
|
||||
|
||||
height: 40px;
|
||||
|
||||
position: relative;
|
||||
|
||||
border-radius: 2px;
|
||||
|
||||
background-color: #dae2d0;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
text-align: center;
|
||||
|
||||
user-select: none;
|
||||
|
||||
-moz-user-select: none;
|
||||
|
||||
-webkit-user-select: none;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#slider_bg {
|
||||
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
|
||||
top: 0;
|
||||
|
||||
height: 100%;
|
||||
|
||||
background-color: #7AC23C;
|
||||
|
||||
z-index: 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#label {
|
||||
|
||||
width: 46px;
|
||||
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
|
||||
top: 0;
|
||||
|
||||
height: 38px;
|
||||
|
||||
line-height: 38px;
|
||||
|
||||
border: 1px solid #cccccc;
|
||||
|
||||
background: #fff;
|
||||
|
||||
z-index: 3;
|
||||
|
||||
cursor: move;
|
||||
|
||||
color: #ff9e77;
|
||||
|
||||
font-size: 16px;
|
||||
|
||||
font-weight: 900;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#labelTip {
|
||||
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
|
||||
height: 100%;
|
||||
|
||||
font-size: 13px;
|
||||
|
||||
font-family: 'Microsoft Yahei', serif;
|
||||
|
||||
color: #787878;
|
||||
|
||||
line-height: 38px;
|
||||
|
||||
text-align: center;
|
||||
|
||||
z-index: 2;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
www.coedq.net
|
||||
|
||||
www.xttblog.com
|
||||
|
||||
*/
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>登录界面</title>
|
||||
<link rel="stylesheet" href="css/reset.css" />
|
||||
<link rel="stylesheet" href="css/common.css" />
|
||||
<link rel="stylesheet" href="css/font-awesome.min.css" />
|
||||
<script type="text/javascript" src="js/jquery.min.js" ></script>
|
||||
<script type="text/javascript" src="js/common.js" ></script>
|
||||
<script type="text/javascript" src="js/md5.min.js"></script>
|
||||
<script type="text/javascript" src="jquery-validation/jquery.validate.min.js"></script>
|
||||
<script type="text/javascript" src="layer/layer.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="layer/layer.js"></script>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/css/slide-unlock.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/slideunlock/slideunlock.js"></script>
|
||||
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
|
||||
|
||||
<style>
|
||||
html, body, h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
background-color: #393939;
|
||||
color: #d5d4ff;
|
||||
overflow: hidden
|
||||
}
|
||||
#demo {
|
||||
width: 600px;
|
||||
margin: 150px auto;
|
||||
padding: 10px;
|
||||
border: 1px dashed #d5d4ff;
|
||||
border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
var slider = new SliderUnlock("#slider",{
|
||||
successLabelTip : "欢迎访问业余草网站"
|
||||
},function(){
|
||||
alert("验证成功,即将跳转至业余草首页");
|
||||
//window.location.href="http://www.xttblog.com"
|
||||
});
|
||||
slider.init();
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="demo">
|
||||
<div id="slider">
|
||||
<div id="slider_bg"></div>
|
||||
<span id="label">>></span> <span id="labelTip">拖动滑块验证</span> </div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,378 @@
|
|||
|
||||
;(function ($,window,document,undefined) {
|
||||
|
||||
function SliderUnlock(elm, options, success){
|
||||
|
||||
var me = this;
|
||||
|
||||
var $elm = me.checkElm(elm) ? $(elm) : $;
|
||||
|
||||
success = me.checkFn(success) ? success : function(){};
|
||||
|
||||
|
||||
|
||||
var opts = {
|
||||
|
||||
successLabelTip: "Successfully Verified",
|
||||
|
||||
duration: 200,
|
||||
|
||||
swipestart: false,
|
||||
|
||||
min: 0,
|
||||
|
||||
max: $elm.width(),
|
||||
|
||||
index: 0,
|
||||
|
||||
IsOk: false,
|
||||
|
||||
lableIndex: 0
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
opts = $.extend(opts, options||{});
|
||||
|
||||
|
||||
|
||||
//$elm
|
||||
|
||||
me.elm = $elm;
|
||||
|
||||
//opts
|
||||
|
||||
me.opts = opts;
|
||||
|
||||
//是否开始滑动
|
||||
|
||||
me.swipestart = opts.swipestart;
|
||||
|
||||
//最小值
|
||||
|
||||
me.min = opts.min;
|
||||
|
||||
//最大值
|
||||
|
||||
me.max = opts.max;
|
||||
|
||||
//当前滑动条所处的位置
|
||||
|
||||
me.index = opts.index;
|
||||
|
||||
//是否滑动成功
|
||||
|
||||
me.isOk = opts.isOk;
|
||||
|
||||
//滑块宽度
|
||||
|
||||
me.labelWidth = me.elm.find('#label').width();
|
||||
|
||||
//滑块背景
|
||||
|
||||
me.sliderBg = me.elm.find('#slider_bg');
|
||||
|
||||
//鼠标在滑动按钮的位置
|
||||
|
||||
me.lableIndex = opts.lableIndex;
|
||||
|
||||
//success
|
||||
|
||||
me.success = success;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
SliderUnlock.prototype.init = function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
|
||||
|
||||
me.updateView();
|
||||
|
||||
me.elm.find("#label").on("mousedown", function (event) {
|
||||
|
||||
var e = event || window.event;
|
||||
|
||||
me.lableIndex = e.clientX - this.offsetLeft;
|
||||
|
||||
me.handerIn();
|
||||
|
||||
}).on("mousemove", function (event) {
|
||||
|
||||
me.handerMove(event);
|
||||
|
||||
}).on("mouseup", function (event) {
|
||||
|
||||
me.handerOut();
|
||||
|
||||
}).on("mouseout", function (event) {
|
||||
|
||||
me.handerOut();
|
||||
|
||||
}).on("touchstart", function (event) {
|
||||
|
||||
var e = event || window.event;
|
||||
|
||||
me.lableIndex = e.originalEvent.touches[0].pageX - this.offsetLeft;
|
||||
|
||||
me.handerIn();
|
||||
|
||||
}).on("touchmove", function (event) {
|
||||
|
||||
me.handerMove(event, "mobile");
|
||||
|
||||
}).on("touchend", function (event) {
|
||||
|
||||
me.handerOut();
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 鼠标/手指接触滑动按钮
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.handerIn = function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
me.swipestart = true;
|
||||
|
||||
me.min = 0;
|
||||
|
||||
me.max = me.elm.width();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 鼠标/手指移出
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.handerOut = function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
//停止
|
||||
|
||||
me.swipestart = false;
|
||||
|
||||
//me.move();
|
||||
|
||||
if (me.index < me.max) {
|
||||
|
||||
me.reset();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 鼠标/手指移动
|
||||
|
||||
* @param event
|
||||
|
||||
* @param type
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.handerMove = function (event, type) {
|
||||
|
||||
var me = this;
|
||||
|
||||
if (me.swipestart) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
event = event || window.event;
|
||||
|
||||
if (type == "mobile") {
|
||||
|
||||
me.index = event.originalEvent.touches[0].pageX - me.lableIndex;
|
||||
|
||||
} else {
|
||||
|
||||
me.index = event.clientX - me.lableIndex;
|
||||
|
||||
}
|
||||
|
||||
me.move();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 鼠标/手指移动过程
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.move = function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
if ((me.index + me.labelWidth) >= me.max) {
|
||||
|
||||
me.index = me.max - me.labelWidth -2;
|
||||
|
||||
//停止
|
||||
|
||||
me.swipestart = false;
|
||||
|
||||
//解锁
|
||||
|
||||
me.isOk = true;
|
||||
|
||||
}
|
||||
|
||||
if (me.index < 0) {
|
||||
|
||||
me.index = me.min;
|
||||
|
||||
//未解锁
|
||||
|
||||
me.isOk = false;
|
||||
|
||||
}
|
||||
|
||||
if (me.index+me.labelWidth+2 == me.max && me.max > 0 && me.isOk) {
|
||||
|
||||
//解锁默认操作
|
||||
|
||||
$('#label').unbind().next('#labelTip').
|
||||
|
||||
text(me.opts.successLabelTip).css({'color': '#fff'});
|
||||
|
||||
|
||||
|
||||
me.success();
|
||||
|
||||
}
|
||||
|
||||
me.updateView();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 更新视图
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.updateView = function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
|
||||
|
||||
me.sliderBg.css('width', me.index);
|
||||
|
||||
me.elm.find("#label").css("left", me.index + "px")
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 重置slide的起点
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.reset = function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
|
||||
|
||||
me.index = 0;
|
||||
|
||||
me.sliderBg .animate({'width':0},me.opts.duration);
|
||||
|
||||
me.elm.find("#label").animate({left: me.index}, me.opts.duration)
|
||||
|
||||
.next("#lableTip").animate({opacity: 1}, me.opts.duration);
|
||||
|
||||
me.updateView();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 检测元素是否存在
|
||||
|
||||
* @param elm
|
||||
|
||||
* @returns {boolean}
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.checkElm = function (elm) {
|
||||
|
||||
if($(elm).length > 0){
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
throw "this element does not exist.";
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 检测传入参数是否是function
|
||||
|
||||
* @param fn
|
||||
|
||||
* @returns {boolean}
|
||||
|
||||
*/
|
||||
|
||||
SliderUnlock.prototype.checkFn = function (fn) {
|
||||
|
||||
if(typeof fn === "function"){
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
throw "the param is not a function.";
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
window['SliderUnlock'] = SliderUnlock;
|
||||
|
||||
})(jQuery, window, document);
|
|
@ -0,0 +1,73 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>登录</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" href="css/reset.css" />
|
||||
<link rel="stylesheet" href="css/common.css" />
|
||||
<link rel="stylesheet" href="css/font-awesome.min.css" />
|
||||
<!-- jquery -->
|
||||
<script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>
|
||||
<!-- bootstrap -->
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/bootstrap.min.css}" />
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/js/bootstrap-3.3.2-dist/css/bootstrap.css}" />
|
||||
<script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script>
|
||||
<!-- jquery-validator -->
|
||||
<script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.min.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/jquery-validation/localization/messages_zh.min.js}"></script>
|
||||
<!-- layer -->
|
||||
<script type="text/javascript" th:src="@{/layer/layer.js}"></script>
|
||||
<!-- md5.js -->
|
||||
<script type="text/javascript" th:src="@{/js/md5.min.js}"></script>
|
||||
<!-- common.js -->
|
||||
<script type="text/javascript" th:src="@{/js/common.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/bootstrap-3.3.2-dist/js/bootstrap.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/plugins/jquery-validation/jquery.validate.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/plugins/jquery-validation/localization/messages_zh.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/plugins/jquery.form.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/jquery.bootstrap.min.js}"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/css/slide-unlock.css}" />
|
||||
<script type="text/javascript" th:src="@{/js/slideunlock/slideunlock.js}"></script>
|
||||
<style>
|
||||
html, body, h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
background-color: #393939;
|
||||
color: #d5d4ff;
|
||||
overflow: hidden
|
||||
}
|
||||
#demo {
|
||||
width: 600px;
|
||||
margin: 150px auto;
|
||||
padding: 10px;
|
||||
border: 1px dashed #d5d4ff;
|
||||
border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="demo">
|
||||
<div id="slider">
|
||||
<div id="slider_bg"></div>
|
||||
<span id="label">>></span> <span id="labelTip">拖动滑块验证</span> </div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
$(function () {
|
||||
var slider = new SliderUnlock("#slider",{
|
||||
successLabelTip : "欢迎访问业余草网站"
|
||||
},function(){
|
||||
alert("验证成功,即将跳转至业余草首页");
|
||||
//window.location.href="http://www.xttblog.com"
|
||||
});
|
||||
slider.init();
|
||||
})
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>拖拽滑动验证码插件 slideunlock.js</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE-edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/css/slide-unlock.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript" src="js/slideunlock/slideunlock.js"></script>
|
||||
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
|
||||
|
||||
<style>
|
||||
html, body, h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
background-color: #393939;
|
||||
color: #d5d4ff;
|
||||
overflow: hidden
|
||||
}
|
||||
#demo {
|
||||
width: 600px;
|
||||
margin: 150px auto;
|
||||
padding: 10px;
|
||||
border: 1px dashed #d5d4ff;
|
||||
border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="demo">
|
||||
<div id="slider">
|
||||
<div id="slider_bg"></div>
|
||||
<span id="label">>></span> <span id="labelTip">拖动滑块验证</span> </div>
|
||||
<script>
|
||||
$(function () {
|
||||
var slider = new SliderUnlock("#slider",{
|
||||
successLabelTip : "欢迎访问业余草网站"
|
||||
},function(){
|
||||
alert("验证成功,即将跳转至业余草首页");
|
||||
//window.location.href="http://www.xttblog.com"
|
||||
});
|
||||
slider.init();
|
||||
})
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -6,14 +6,15 @@ import lombok.NoArgsConstructor;
|
|||
import lombok.Setter;
|
||||
import org.apache.ibatis.type.Alias;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Alias("goodsVo")
|
||||
public class GoodsVo {
|
||||
@Alias("goodsVoOrder")
|
||||
public class GoodsVoOrder implements Serializable {
|
||||
private Long id;
|
||||
private String goodsName;
|
||||
private String goodsTitle;
|
|
@ -0,0 +1,23 @@
|
|||
package com.geekq.api.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.ibatis.type.Alias;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Alias("MiaoshaGoods")
|
||||
public class MiaoshaGoods implements Serializable {
|
||||
private Long id;
|
||||
private Long goodsId;
|
||||
private Integer stockCount;
|
||||
private Date startDate;
|
||||
private Date endDate;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package com.geekq.api.service;
|
||||
|
||||
/**
|
||||
* DemoService
|
||||
* 服务Api接口类
|
||||
* @author geekq
|
||||
* @date 2018/6/6
|
||||
*/
|
||||
public interface DemoService {
|
||||
|
||||
String sayHello(String name);
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.geekq.api.service;
|
||||
|
||||
import com.geekq.api.entity.GoodsVo;
|
||||
import com.geekq.common.utils.resultbean.ResultGeekQ;
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.api.utils.ResultGeekQOrder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -10,5 +10,22 @@ import java.util.List;
|
|||
*/
|
||||
public interface GoodsService {
|
||||
|
||||
public ResultGeekQ<List<GoodsVo>> listGoodsVo();
|
||||
/**
|
||||
* 查询获取全部信息
|
||||
* @return
|
||||
*/
|
||||
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo();
|
||||
|
||||
/**
|
||||
* 根据商品id查询货物信息
|
||||
* @param goodsId
|
||||
* @return
|
||||
*/
|
||||
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId);
|
||||
|
||||
/**
|
||||
* 减库存
|
||||
* @return
|
||||
*/
|
||||
public boolean reduceStock(GoodsVoOrder goods);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.geekq.api.service;
|
||||
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.api.service.GoodsService;
|
||||
import com.geekq.api.utils.ResultGeekQOrder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 邱润泽
|
||||
*/
|
||||
@Service
|
||||
public class GoodsServiceMock implements GoodsService {
|
||||
@Override
|
||||
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo() {
|
||||
List<GoodsVoOrder> list1 = new ArrayList<>();
|
||||
ResultGeekQOrder<List<GoodsVoOrder>> list = ResultGeekQOrder.build();
|
||||
list.setData(list1);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reduceStock(GoodsVoOrder goods) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.geekq.api.utils;
|
||||
|
||||
|
||||
|
||||
public class AbstractResultOrder {
|
||||
private ResultStatusOrder status;
|
||||
private int code;
|
||||
private String message;
|
||||
protected AbstractResultOrder() {
|
||||
}
|
||||
protected AbstractResultOrder(ResultStatusOrder status, String message) {
|
||||
this.code = status.getCode();
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
protected AbstractResultOrder(ResultStatusOrder status) {
|
||||
this.code = status.getCode();
|
||||
this.message = status.getMessage();
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public static boolean isSuccess(AbstractResultOrder result) {
|
||||
return result != null && result.status == ResultStatusOrder.SUCCESS && result.getCode() == ResultStatusOrder.SUCCESS.getCode();
|
||||
}
|
||||
|
||||
public AbstractResultOrder withError(ResultStatusOrder status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AbstractResultOrder withError(String message) {
|
||||
this.status = ResultStatusOrder.SYSTEM_ERROR;
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AbstractResultOrder withError(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AbstractResultOrder success() {
|
||||
this.status = ResultStatusOrder.SUCCESS;
|
||||
return this;
|
||||
}
|
||||
public ResultStatusOrder getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message == null ? this.status.getMessage() : this.message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.geekq.api.utils;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class ResultGeekQOrder<T> extends AbstractResultOrder implements Serializable {
|
||||
private static final long serialVersionUID = 867933019328199779L;
|
||||
private T data;
|
||||
private Integer count;
|
||||
|
||||
protected ResultGeekQOrder() {
|
||||
}
|
||||
protected ResultGeekQOrder(ResultStatusOrder status, String message) {
|
||||
super(status, message);
|
||||
}
|
||||
protected ResultGeekQOrder(ResultStatusOrder status) {
|
||||
super(status);
|
||||
}
|
||||
public static <T> ResultGeekQOrder<T> build() {
|
||||
return new ResultGeekQOrder(ResultStatusOrder.SUCCESS, (String)null);
|
||||
}
|
||||
|
||||
public static <T> ResultGeekQOrder<T> build(String message) {
|
||||
return new ResultGeekQOrder(ResultStatusOrder.SUCCESS, message);
|
||||
}
|
||||
|
||||
public static <T> ResultGeekQOrder<T> error(ResultStatusOrder status) {
|
||||
return new ResultGeekQOrder<T>(status);
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Integer getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public void success(T value) {
|
||||
this.success();
|
||||
this.data = value;
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package com.geekq.api.utils;
|
||||
|
||||
/**
|
||||
* 普通返回类
|
||||
* 1打头 系统系列错误
|
||||
* 2 注册登录系列错误
|
||||
* 3 check 系列错误
|
||||
* 4 秒杀错误
|
||||
* 5 商品错误
|
||||
* 6 订单错误
|
||||
* @author qiurunze
|
||||
*/
|
||||
public enum ResultStatusOrder {
|
||||
SUCCESS(0, "成功"),
|
||||
FAILD(-1, "失败"),
|
||||
EXCEPTION(-1, "系统异常"),
|
||||
PARAM_ERROR(10000, "参数错误"),
|
||||
SYSTEM_ERROR(10001, "系统错误"),
|
||||
FILE_NOT_EXIST(10002, "文件不存在"),
|
||||
FILE_NOT_DOWNLOAD(10003, "文件没有下载"),
|
||||
FILE_NOT_GENERATE(10004, "文件没有生成"),
|
||||
FILE_NOT_STORAGE(10005, "文件没有入库"),
|
||||
SYSTEM_DB_ERROR(10006, "数据库系统错误"),
|
||||
FILE_ALREADY_DOWNLOAD(10007, "文件已经下载"),
|
||||
DATA_ALREADY_PEXISTS(10008, "数据已经存在"),
|
||||
|
||||
|
||||
/**
|
||||
* 注册登录
|
||||
*/
|
||||
RESIGETR_SUCCESS(20000,"注册成功!"),
|
||||
RESIGETER_FAIL(200001,"注册失败!"),
|
||||
CODE_FAIL(200002,"验证码不一致!"),
|
||||
|
||||
/**
|
||||
* check
|
||||
*/
|
||||
BIND_ERROR (30001,"参数校验异常:%s"),
|
||||
ACCESS_LIMIT_REACHED (30002,"请求非法!"),
|
||||
REQUEST_ILLEGAL (30004,"访问太频繁!"),
|
||||
SESSION_ERROR (30005,"Session不存在或者已经失效!"),
|
||||
PASSWORD_EMPTY (30006,"登录密码不能为空!"),
|
||||
MOBILE_EMPTY (30007,"手机号不能为空!"),
|
||||
MOBILE_ERROR (30008,"手机号格式错误!"),
|
||||
MOBILE_NOT_EXIST (30009,"账号不存在!"),
|
||||
PASSWORD_ERROR (30010,"密码错误!"),
|
||||
USER_NOT_EXIST(30011,"用户不存在!"),
|
||||
|
||||
/**
|
||||
* 订单模块
|
||||
*/
|
||||
ORDER_NOT_EXIST(60001,"订单不存在"),
|
||||
|
||||
/**
|
||||
* 秒杀模块
|
||||
*/
|
||||
MIAO_SHA_OVER(40001,"商品已经秒杀完毕"),
|
||||
REPEATE_MIAOSHA(40002,"不能重复秒杀"),
|
||||
MIAOSHA_FAIL(40003,"秒杀失败"),
|
||||
ORDER_GET_FAIL(40004,"订单获取失败");
|
||||
|
||||
/**
|
||||
* 商品模块
|
||||
*/
|
||||
private int code;
|
||||
private String message;
|
||||
|
||||
private ResultStatusOrder(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
public String getOutputName() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
private ResultStatusOrder(Object... args) {
|
||||
this.message = String.format(this.message, args);
|
||||
}
|
||||
}
|
|
@ -38,7 +38,32 @@
|
|||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<!--<includes>-->
|
||||
<!--<include>**/*.properties</include>-->
|
||||
<!--<include>**/*.xml</include>-->
|
||||
<!--<include>**/*.ini</include>-->
|
||||
<!--</includes>-->
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource> <!--配置文件路径 -->
|
||||
<directory>src/main/resources</directory> <!--这里对应项目存放配置文件的目录--> <!--开启filtering功能 -->
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<!--<include>application-${activatedProperties}.properties</include>-->
|
||||
<include>application.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.geekq.provider;
|
||||
|
||||
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
|
||||
/**
|
||||
* DubboProviderApplication
|
||||
|
@ -11,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||
* @author geekq
|
||||
* @date 2018/6/7
|
||||
*/
|
||||
@EnableDubbo
|
||||
@ImportResource(value={"classpath:provider.xml"})
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.geekq.provider.mapper")
|
||||
public class DubboProviderApplication {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.geekq.provider.mapper;
|
||||
|
||||
import com.geekq.api.entity.GoodsVo;
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.api.entity.MiaoshaGoods;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -10,9 +11,10 @@ import java.util.List;
|
|||
*/
|
||||
public interface GoodsMapper {
|
||||
|
||||
public List<GoodsVo> listGoodsVo();
|
||||
public List<GoodsVoOrder> listGoodsVo();
|
||||
|
||||
public GoodsVo getGoodsVoByGoodsId(@Param("goodsId") long goodsId);
|
||||
public GoodsVoOrder getGoodsVoByGoodsId(@Param("goodsId") long goodsId);
|
||||
|
||||
public int reduceStock(MiaoshaGoods g);
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="com.geekq.provider.mapper.GoodsMapper" >
|
||||
|
||||
<resultMap id="BaseResultMap" type="goodsVo" >
|
||||
<resultMap id="BaseResultMap" type="goodsVoOrder" >
|
||||
<id column="id" property="id" jdbcType="BIGINT" />
|
||||
<result column="goods_name" property="goodsName" jdbcType="VARCHAR" />
|
||||
<result column="goods_title" property="goodsTitle" jdbcType="VARCHAR" />
|
||||
|
@ -32,4 +32,8 @@
|
|||
WHERE miaosha_goods.goods_id = #{goodsId,jdbcType=BIGINT}
|
||||
</select>
|
||||
|
||||
<update id="reduceStock" >
|
||||
update miaosha_goods set stock_count = stock_count - 1
|
||||
where goods_id = #{goodsId} and stock_count > 0
|
||||
</update>
|
||||
</mapper>
|
|
@ -1,20 +0,0 @@
|
|||
package com.geekq.provider.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
import com.geekq.api.service.DemoService;
|
||||
|
||||
/**
|
||||
* DemoServiceImpl
|
||||
* 服务提供类
|
||||
* @author geekq
|
||||
* @date 2018/6/7
|
||||
*/
|
||||
@Service(version = "${demo.service.version}")
|
||||
public class DemoServiceImpl implements DemoService {
|
||||
|
||||
@Override
|
||||
public String sayHello(String name) {
|
||||
System.out.println("2321121212312312");
|
||||
return "Hello, " + name + " (from Spring Boot)";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.geekq.provider.service.impl;
|
||||
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.api.service.GoodsService;
|
||||
import com.geekq.api.utils.ResultGeekQOrder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 邱润泽
|
||||
*/
|
||||
@Service("goodGroupService")
|
||||
public class GoodsGroupServiceImpl implements GoodsService {
|
||||
@Override
|
||||
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo() {
|
||||
|
||||
System.out.println("测试 group!");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId) {
|
||||
System.out.println("测试 group!");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reduceStock(GoodsVoOrder goods) {
|
||||
System.out.println("测试 group!");
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,33 +1,64 @@
|
|||
package com.geekq.provider.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
import com.geekq.api.entity.GoodsVo;
|
||||
import com.geekq.api.entity.GoodsVoOrder;
|
||||
import com.geekq.api.entity.MiaoshaGoods;
|
||||
import com.geekq.api.service.GoodsService;
|
||||
import com.geekq.common.enums.ResultStatus;
|
||||
import com.geekq.common.utils.resultbean.ResultGeekQ;
|
||||
import com.geekq.api.utils.ResultGeekQOrder;
|
||||
import com.geekq.api.utils.ResultStatusOrder;
|
||||
import com.geekq.provider.mapper.GoodsMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 邱润泽
|
||||
*/
|
||||
@Service(version = "${demo.service.version}")
|
||||
@Service("goodsService")
|
||||
public class GoodsServiceImpl implements GoodsService {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(GoodsServiceImpl.class);
|
||||
|
||||
|
||||
@Autowired
|
||||
GoodsMapper goodsMapper;
|
||||
|
||||
@Override
|
||||
public ResultGeekQ<List<GoodsVo>> listGoodsVo() {
|
||||
ResultGeekQ resultGeekQ = ResultGeekQ.build();
|
||||
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo() {
|
||||
|
||||
ResultGeekQOrder<List<GoodsVoOrder>> resultGeekQ = ResultGeekQOrder.build();
|
||||
try {
|
||||
resultGeekQ.setData(goodsMapper.listGoodsVo());
|
||||
} catch (Exception e) {
|
||||
resultGeekQ.withError(ResultStatus.SYSTEM_ERROR);
|
||||
logger.error("获取订单数据失败!",e);
|
||||
resultGeekQ.withError(ResultStatusOrder.ORDER_GET_FAIL);
|
||||
}
|
||||
return resultGeekQ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId) {
|
||||
ResultGeekQOrder<GoodsVoOrder> resultGeekQ = ResultGeekQOrder.build();
|
||||
|
||||
try {
|
||||
GoodsVoOrder goodsVoOrder = goodsMapper.getGoodsVoByGoodsId(goodsId);
|
||||
resultGeekQ.setData(goodsVoOrder);
|
||||
} catch (Exception e) {
|
||||
logger.error("获取单个订单失败!",e);
|
||||
resultGeekQ.withError(ResultStatusOrder.ORDER_GET_FAIL);
|
||||
}
|
||||
return resultGeekQ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reduceStock(GoodsVoOrder goods) {
|
||||
MiaoshaGoods g = new MiaoshaGoods();
|
||||
g.setGoodsId(goods.getId());
|
||||
int ret = goodsMapper.reduceStock(g);
|
||||
return ret > 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
spring.application.name = miaosha-order-provider
|
||||
server.port = 9090
|
||||
#spring.application.name = miaosha-order-provider
|
||||
#server.port = 9090
|
||||
#dubbo.application.name = miaosha-order-provider
|
||||
#demo.service.version = 1.0.0
|
||||
#dubbo.protocol.name = dubbo
|
||||
#dubbo.protocol.port = 20880
|
||||
#dubbo.registry.address = zookeeper://localhost:2181
|
||||
#dubbo.provider.timeout = 1000
|
||||
|
||||
dubbo.application.name = miaosha-order-provider
|
||||
|
||||
demo.service.version = 1.0.0
|
||||
|
||||
dubbo.protocol.name = dubbo
|
||||
dubbo.protocol.port = 20880
|
||||
|
||||
dubbo.registry.address = zookeeper://localhost:2181
|
||||
|
||||
dubbo.provider.timeout = 1000
|
||||
|
||||
|
||||
mybatis.type-aliases-package=com.geekq.api.entity
|
||||
|
@ -34,3 +30,5 @@ spring.datasource.testOnBorrow=false
|
|||
spring.datasource.testOnReturn=false
|
||||
spring.datasource.poolPreparedStatements=true
|
||||
spring.datasource.maxOpenPreparedStatements=20
|
||||
|
||||
server.port = 9090
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||
|
||||
<!-- 为当前服务提供者取个名字,并且提供给注册中心 -->
|
||||
<dubbo:application name="miaosha-order-service"></dubbo:application>
|
||||
|
||||
<!-- 注册中心的配置,使用zk暴露服务 -->
|
||||
<dubbo:registry protocol="zookeeper" address="localhost:2181"></dubbo:registry>
|
||||
|
||||
<!-- 定义暴露服务的端口号 -->
|
||||
<dubbo:protocol name="dubbo" port="20880" ></dubbo:protocol>
|
||||
|
||||
<!-- 暴露具体的服务接口 本地伪装-->
|
||||
<dubbo:service retries="3" interface="com.geekq.api.service.GoodsService"
|
||||
ref="goodsService" group="goods2" timeout="6000" mock="true">
|
||||
<dubbo:method name="listGoodsVo" timeout="3000" ></dubbo:method>
|
||||
</dubbo:service>
|
||||
|
||||
<dubbo:service interface="com.geekq.api.service.GoodsService" ref="goodGroupService" group="goods1"></dubbo:service>
|
||||
|
||||
|
||||
</beans>
|
|
@ -47,17 +47,18 @@
|
|||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>${org.mybatis.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.geekq</groupId>
|
||||
<artifactId>miaosha-common</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>com.geekq</groupId>-->
|
||||
<!--<artifactId>miaosha-common</artifactId>-->
|
||||
<!--<version>0.0.1-SNAPSHOT</version>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.boot</groupId>
|
||||
|
|
Loading…
Reference in New Issue
Block a user