1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/miozus-gulimall

Клонировать/Скачать
README.md 23 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 30.11.2024 10:28 0a202fe

Перевод текста:

Все мои усилия — пародия на 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 постоянный слой фреймворк и т. д. img.png
2 Членство SpringWeb перехватчик + JWT аутентификация, Oauth2.0 третья сторона авторизации img.png
3 Поиск ElasticSearch поиск img.png
4 Заказ, корзина Redis распределённое кэширование, блокировка, проверка уникальности, RabbitMQ очередь сообщений img.png
5 Маршрутизация, обнаружение центра Alibaba-Nacos регистрация и конфигурация центра, OpenFeign коммуникация микросервиса, SpringBoot-Gateway маршрутизация nacos.png
6 Третья сторона oss галерея изображений, SMS-подтверждение

Основные услуги инфраструктуры (технологический стек) также включают:

Номер Базовая инфраструктура Технологический стек Снимок экрана
1 Сервер Docker развёртывание промежуточного программного обеспечения docker-server..png
2 Тестирование Selenium (Python) модульное тестирование img.png Онлайн-развёртывание: быстрое начало
  1. Конфигурация

Конкретные рекомендации см. в обучающих видео или других заметках с открытым исходным кодом Gulimall. Благодаря Nacos, который управляет конфигурацией каждого микросервиса, конфигурация становится сложной и разнообразной, но хорошо, что она сохраняется в одной базе данных. Автор использует 2G * 2 сервера с памятью, которая слишком мала, поэтому здесь не будет подробно описано совместное тестирование.

— [ ] Последующая перестройка проекта скроет информацию об учётных записях, добавит аннотации к открытому файлу конфигурации и откроет Notion для заметок о разработке, чтобы научить вас создавать систему электронной коммерции с нуля.

  1. Развёртывание

База данных и промежуточное ПО развёрнуты на облачном сервере Alibaba (1 ядро 2G), а все экземпляры SpringCloud микросервисной системы запущены на локальном компьютере (5G памяти, без аппаратной поддержки для просмотра проекта онлайн), в основном из-за сетевых задержек и влияния промежуточного ПО, а пропускная способность тестирования нагрузки составляет 9 /s.

— [ ] Если развернуть на сервере с большим объёмом памяти и добавить несколько серверов в кластер, можно продемонстрировать его способность поддерживать высокую параллельность и доступность (если у автора есть условия для развёртывания, он проведёт дополнительное тестирование нагрузки).

Перестройка проекта

Курс не только объясняет использование основных фреймворков, но и демонстрирует основные операции добавления, удаления, изменения и запроса, но зрители неоднозначно оценивают бизнес-логику.

Автор придерживается принципа простоты и практичности и ссылается на некоторые проекты торговых центров с открытым исходным кодом (например, yami-shop, renren-fast) и статьи Java-Guide о технологиях Spring, пытаясь перестроить проект в следующих направлениях (это выходит за рамки курса и вызывает зависимость от перестройки).

🍽️ Spring AOP: аспектно-ориентированное программирование

1. Глобальные исключения: реализованы на нижнем уровне и перехвачены на верхнем уровне управления.
  1. Он находится в общем сервисе common и охватывает три категории исключений: базовые исключения, исключения проверки параметров интерфейса и пользовательские исключения для торговых сервисов.
  2. Пользовательское исключение торгового сервиса GuliMallBindException включает в себя общий универсальный класс перечисления исключений BizCodeEnum.
/**
 * Конфигурация обработчика исключений по умолчанию
 */
@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());
    }
}
2. Управление кешем: управление операциями добавления, удаления, изменения, запроса, проверки токенов, проверки уникальности.

/**
 * Аспект кеша товаров корзины 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();
    }
    // ...
}
3. Очередь сообщений: разделение дополнительных уведомлений, развязка кода бизнес-логики.
/**
 * Очередь сообщений о заказах
 */
@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;
    }
    // ...
}
4. Системный журнал: аудит ключевых функций, времени выполнения, параметров и возвращаемых значений, а также сохранение их в постоянном хранилище. (Действует только для одного микросервиса, требуется очередь сообщений или межсерверное взаимодействие.)
/**
 * Системный журнал
 */
@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;

Селен тестирование с использованием фреймворка

Создан простой тестовый фреймворк с нуля.

  • Дизайн:
    • PO — ориентирован на страницу, реализует три уровня кода для развязки: селектор элементов + шаблон объекта движка браузера + написание модульных тестов.
    • Синглтон — объект журнала и объект браузера должны быть только один экземпляр, используется двойная проверка блокировки для обеспечения безопасности в многопоточной среде.
    • Декоратор — инкапсулирует метод URL-маршрутизации, обычно операции щелчка требуют открытия веб-страницы.
    • Шаблон — вышеупомянутые модели инкапсулированы в модули, при написании новой страницы просто вызываются компоненты, а при написании тестовых примеров вызываются страница, метод и данные.
  • Имитация человеческого процесса:
    • Тестирование выявило и исправило проблемы с заголовком документа, скрытием входа после входа в систему и потерей запросов Feign из-за изоляции уровня Hystrix.
  • Отсутствие тестирования интерфейса:
    • В будущем планируется использовать инструмент Apifox для рефакторинга.

Пример декоратора

Декоратор не что иное, как абстракция 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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/miozus-gulimall.git
git@api.gitlife.ru:oschina-mirror/miozus-gulimall.git
oschina-mirror
miozus-gulimall
miozus-gulimall
master