Перевод текста:
Все мои усилия — пародия на JD.COM с 2019 года.
Приблизительный перевод названия сервиса SpringCloud — Спринг Клауд.
SpringCLoud
SpringCLoud
[Срочное уведомление] Моя база данных была удалена и подверглась вымогательству со стороны хакеров, но я не знаю, как её восстановить.
Пожалуйста, оплатите определённую сумму, чтобы восстановить базу данных. Для этого свяжитесь с нами по электронной почте в формате:
Тема письма: IP-адрес вашей базы данных
Текст письма: восстановление bdhuawei@protonmail.com
Это журнал доступа к MySQL за период с 7 по 11 июня в контейнере.
2022-06-07T00:43:26.990331Z 740 [Warning] [MY-010055] [Server] IP address '139.196.98.39' could not be resolved: Name or service not known
2022-06-07T01:27:30.136113Z 744 [Warning] [MY-010055] [Server] IP address '221.199.70.144' could not be resolved: Name or service not known
⭐ 2022-06-07T01:27:30.154238Z 743 [Warning] [MY-010057] [Server] IP address '171.34.177.27' has been resolved to the host name '27.177.34.171.adsl-pool.jx.chinaunicom.com', which resembles IPv4-address itself.
2022-06-08T03:56:03.021368Z 853 [Warning] [MY-010055] [Server] IP address '101.132.126.80' could not be resolved: Name or service not known
2022-06-08T14:49:16.797060Z 898 [Warning] [MY-010055] [Server] IP address '85.209.42.233' could not be resolved: Name or service not known
2022-06-08T16:08:49.537765Z 905 [Warning] [MY-010055] [Server] IP address '117.61.11.99' could not be resolved: Name or service not known
mbind: Operation not permitted
2022-06-09T03:12:33.700988Z 965 [Warning] [MY-010055] [Server] IP address '36.57.85.252' could not be resolved: Name or service not known
2022-06-09T03:14:36.436575Z 966 [Warning] [MY-010055] [Server] IP address '47.100.194.160' could not be resolved: Name or service not known
2022-06-09T09:38:21.073759Z 993 [Warning] [MY-010055] [Server] IP address '120.77.26.203' could not be resolved: Name or service not known
2022-06-09T14:09:48.908469Z 1046 [Warning] [MY-010056] [Server] Host name '87-243-171-53.ainet.at' could not be resolved: Name or service not known
2022-06-09T14:12:42.736075Z 1047 [Warning] [MY-010055] [Server] IP address '39.170.17.27' could not be resolved: Temporary failure in name resolution
2022-06-09T18:57:11.958536Z 1070 [Warning] [MY-010055] [Server] IP address '39.99.158.136' could not be resolved: Name or service not known
2022-06-09T20:04:28.374306Z 1076 [Warning] [MY-010055] [Server] IP address '36.6.58.31' could not be resolved: Name or service not known
2022-06-09T20:21:27.999047Z 1079 [Warning] [MY-010055] [Server] IP address '47.101.201.167' could not be resolved: Name or service not known
2022-06-10T08:17:51.431031Z 1129 [Warning] [MY-010055] [Server] IP address '103.167.151.206' could not be resolved: Name or service not known
mbind: Operation not permitted
2022-06-10T09:53:54.666360Z 1137 [Warning] [MY-010056] [Server] Host name 'Host-by.nerocloud.io' could not be resolved: Name or service not known
mbind: Operation not permitted
2022-06-10T20:59:35.958942Z 18127 [Warning] [MY-010055] [Server] IP address '8.142.112.1' could not be resolved: Name or service not known
2022-06-10T22:13:21.794196Z 20024 [Warning] [MY-010055] [Server] IP address '47.101.204.96' could not be resolved: Name or service not known
⭐ 2022-06-11T02:08:21.961647Z 26066 [Warning] [MY-010057] [Server] IP address '118.81.0.141' has been resolved to the host name '141.0.81.118.adsl-pool.sx.cn', which resembles IPv4-address itself.
2022-06-11T02:08:27.907632Z 26065 [Warning] [MY-010055] [Server] IP address '1.85.219.13' could not be resolved: Temporary failure in name resolution
2022-06-11T02:13:51.578978Z 26208 [Warning] [MY-010055] [Server] IP address '117.69.183.164' could not be resolved: Name or service not known
2022-06-11T03:34:35.879666Z 28284 [Warning] [MY-010055] [Server] IP address '60.166.164.184' could not be resolved: Name or service not known
2022-06-11T03:48:39.265416Z 28646 [Warning] [MY-010055] [Server] IP address '113.75.138.24' could not be resolved: Name or service not known
2022-06-11T11:02:47.742152Z 39804 [Warning] [MY-010055] [Server] IP address '111.224.7.171' could not be resolved: Name or service not known
В запросе текст технической направленности из области разработки и тестирования программного обеспечения. Основной язык текста запроса — китайский. 2022-06-11T11:02:47.836884Z 39805 [Warning] [MY-010055] [Server] IP адрес '110.177.176.229' не может быть разрешён: Name or service not known
2022-06-11T14:03:09.876478Z 44443 [Warning] [MY-010055] [Server] IP адрес '117.69.128.30' не может быть разрешён: Name or service not known
2022-06-11T16:07:39.498941Z 47643 [Warning] [MY-010055] [Server] IP адрес '39.103.163.187' не может быть разрешён: Name or service not known
2022-06-11T21:01:32.291036Z 55198 [Warning] [MY-010055] [Server] IP адрес '106.15.192.48' не может быть разрешён: Name or service not known
查看 binlog 日志,它写入 recover 表后,清空了 binlog ,所以不能从 binlog 恢复了。
root@d21c916a0f46:/var/lib/mysql# mysqlbinlog binlog.000001
# The proper term is pseudo_replica_mode, but we use this compatibility alias
# to make the statement usable on server versions 8.0.24 and older.
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
⭐ #220610 9:54:03 server id 1 end_log_pos 125 CRC32 0x73d96118 Start: binlog v 4, server v 8.0.26 created 220610 9:54:03 at startup
ROLLBACK/*!*/;
BINLOG '
uxSjYg8BAAAAeQAAAH0AAAAAAAQAOC4wLjI2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAC7FKNiEwANAAgAAAAABAAEAAAAYQAEGggAAAAICAgCAAAACgoKKioAEjQA
CigBGGHZcw==
'/*!*/;
# at 125
#220610 9:54:03 server id 1 end_log_pos 156 CRC32 0x2c1c2a83 Previous-GTIDs
# [empty]
# at 156
#220612 2:57:59 server id 1 end_log_pos 179 CRC32 0x349c52f8 Stop
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
推测原因:脚本扫描 3036 端口,暴力破解 root 账号。
Структура проекта
❯ tree -L 1
.
├── docs 文档说明
├── gulimall-admin 微服务健康监控中心
├── gulimall-auth 登录鉴权
├── gulimall-cart 购物车
├── gulimall-common 开发脚手架
├── gulimall-coupon 优惠券
├── gulimall-gateway 路由
├── gulimall-member 会员
├── gulimall-order 订单
├── gulimall-plugins 第三方服务
├── gulimall-product 商品
├── gulimall-search 搜索
├── gulimall-seckill 秒杀
├── gulimall-ware 仓库
├── renren-fast 后台管理
├── renren-fast-vue 后台页面
├── renren-generator 低代码开发生成数据库CRUD模型
└── selenium 自动化测试
Проектная информация
Проект представляет собой имитацию электронной коммерции, основанной на архитектуре микросервисов SpringCloud и MVC. Проект включает в себя функции управления товарами, меню, регистрацией и входом пользователей, поиском товаров, оформлением заказов, оплатой через платёжную систему Alipay и другие услуги. Проект разделён на несколько типов микросервисов в зависимости от используемых технологий:
Номер | Микросервис | Технологический стек | Снимок экрана |
---|---|---|---|
1 | Товары, запасы, купоны | MySQL база данных, MyBatisPlus постоянный слой фреймворк и т. д. | ![]() |
2 | Членство | SpringWeb перехватчик + JWT аутентификация, Oauth2.0 третья сторона авторизации | ![]() |
3 | Поиск | ElasticSearch поиск | ![]() |
4 | Заказ, корзина | Redis распределённое кэширование, блокировка, проверка уникальности, RabbitMQ очередь сообщений | ![]() |
5 | Маршрутизация, обнаружение центра | Alibaba-Nacos регистрация и конфигурация центра, OpenFeign коммуникация микросервиса, SpringBoot-Gateway маршрутизация | ![]() |
6 | Третья сторона | oss галерея изображений, SMS-подтверждение |
Основные услуги инфраструктуры (технологический стек) также включают:
Номер | Базовая инфраструктура | Технологический стек | Снимок экрана |
---|---|---|---|
1 | Сервер | Docker развёртывание промежуточного программного обеспечения | ![]() |
2 | Тестирование | Selenium (Python) модульное тестирование |
![]() |
Конкретные рекомендации см. в обучающих видео или других заметках с открытым исходным кодом Gulimall. Благодаря Nacos, который управляет конфигурацией каждого микросервиса, конфигурация становится сложной и разнообразной, но хорошо, что она сохраняется в одной базе данных. Автор использует 2G * 2 сервера с памятью, которая слишком мала, поэтому здесь не будет подробно описано совместное тестирование.
— [ ] Последующая перестройка проекта скроет информацию об учётных записях, добавит аннотации к открытому файлу конфигурации и откроет Notion для заметок о разработке, чтобы научить вас создавать систему электронной коммерции с нуля.
База данных и промежуточное ПО развёрнуты на облачном сервере Alibaba (1 ядро 2G), а все экземпляры SpringCloud микросервисной системы запущены на локальном компьютере (5G памяти, без аппаратной поддержки для просмотра проекта онлайн), в основном из-за сетевых задержек и влияния промежуточного ПО, а пропускная способность тестирования нагрузки составляет 9 /s.
— [ ] Если развернуть на сервере с большим объёмом памяти и добавить несколько серверов в кластер, можно продемонстрировать его способность поддерживать высокую параллельность и доступность (если у автора есть условия для развёртывания, он проведёт дополнительное тестирование нагрузки).
Перестройка проекта
Курс не только объясняет использование основных фреймворков, но и демонстрирует основные операции добавления, удаления, изменения и запроса, но зрители неоднозначно оценивают бизнес-логику.
Автор придерживается принципа простоты и практичности и ссылается на некоторые проекты торговых центров с открытым исходным кодом (например, yami-shop, renren-fast) и статьи Java-Guide о технологиях Spring, пытаясь перестроить проект в следующих направлениях (это выходит за рамки курса и вызывает зависимость от перестройки).
/**
* Конфигурация обработчика исключений по умолчанию
*/
@Controller
@RestControllerAdvice
public class DefaultExceptionHandlerConfig {
@ExceptionHandler(BindException.class)
public ResponseEntity<String> bindExceptionHandler(BindException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getBindingResult().getFieldErrors().get(0).getDefaultMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getBindingResult().getFieldErrors().get(0).getDefaultMessage());
}
@ExceptionHandler(GuliMallBindException.class)
public ResponseEntity<String> unauthorizedExceptionHandler(GuliMallBindException e) {
e.printStackTrace();
return ResponseEntity.status(e.getBizCode()).body(e.getMessage());
}
}
/**
* Аспект кеша товаров корзины Redis
*/
@Aspect
@Component
@Order(1)
public class OrderRedisAspect {
@Autowired
StringRedisTemplate redisTemplate;
private final String CART_PREFIX = "gulimall:cart:";
@Around(value = "@annotation(idempotent)")
public Object checkIdempotentRedisCache(ProceedingJoinPoint pjp, Idempotent idempotent) throws Throwable {
OrderSubmitVo args = (OrderSubmitVo) pjp.getArgs()[0];
Long execute = deleteKeyIfExistTokenRedis(args);
if (execute == 0L) {
throw new GuliMallBindException("Проверка токена не удалась, пожалуйста, не отправляйте заказ повторно");
}
return pjp.proceed();
}
// ...
}
/**
* Очередь сообщений о заказах
*/
@Aspect
@Component
@Order(2)
public class OrderRabbitMqAspect {
@Lazy
@Autowired
RabbitTemplate rabbitTemplate;
@AfterReturning(value = "@annotation(postRabbitMq)", returning = "retVal")
public Object sendRabbitMq(JoinPoint point, Object retVal, PostRabbitMq postRabbitMq) {
if (Objects.nonNull(retVal)) {
// Создать заказ: отправить сообщение после создания
OrderEntity order = (OrderEntity) retVal;
pushDelayQueueAfterSubmitOrder(order);
} else {
// Закрыть заказ: дважды подтвердить разблокировку запасов
OrderEntity methodArg = (OrderEntity) point.getArgs()[0];
pushReleaseQueueAfterCancelOrderForSure(methodArg);
}
return retVal;
}
// ...
}
/**
* Системный журнал
*/
@Component
@Aspect
@Slf4j
public class SysLogAspect {
// @Autowired
// private SysLogService sysLogService;
@Around("@annotation(sysLog)")
public Object around(ProceedingJoinPoint joinPoint, SysLog sysLog) throws Throwable {
``` ```
long beginTime = SystemClock.now();
// Выполнение метода
Object result = joinPoint.proceed();
// Время выполнения (в миллисекундах)
long time = SystemClock.now() - beginTime;
SysLogTo sysLogTo = new SysLogTo();
if (sysLog != null) {
// Описание из аннотации
sysLogTo.setOperation(sysLog.value());
}
// Имя класса запроса
String className = joinPoint.getTarget().getClass().getName();
// Имя метода запроса
String methodName = joinPoint.getSignature().getName();
sysLogTo.setMethod(className + "." + methodName + "()");
// Аргументы запроса
Object[] args = joinPoint.getArgs();
String params = JSONUtil.toJsonStr(args[0]);
sysLogTo.setParams(params);
// Установка IP-адреса
sysLogTo.setIp(IpHelper.getIpAddr());
// // Имя пользователя: требуется поддержка Shiro или Spring-Security
// String username = SecurityUtils.getSysUser().getUsername();
// sysLogEntity.setUsername(username);
sysLogTo.setTime(time);
sysLogTo.setCreateDate(new Date());
// Сохранение системного журнала
log.info("sysLogEntity {} ", sysLogTo);
// sysLogService.save(sysLogEntity);
return result;
Селен тестирование с использованием фреймворка
Создан простой тестовый фреймворк с нуля.
Пример декоратора
Декоратор не что иное, как абстракция AOP.
class mapping(object):
def __init__(self):
""" Не позволяет создавать экземпляры """
return False
@staticmethod
def get(url):
"""
Открыть веб-страницу, затем выполнить ваш метод
"""
if isinstance(url, Enum):
url = url.value
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if driver.current_url != url:
log.info(f'[GET] {url} [{func.__name__}]')
driver.get(url)
return func(*args, **kwargs)
return wrapper
return decorator
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )