0) Предисловие
После разработки веб-приложения оно развертывается в Tomcat или других контейнерах для доступа пользователей.Для небольших приложений Tomcat устанавливается на сервер, а веб-приложение развертывается.По мере увеличения трафика нагрузка на Tomcat будет увеличиваться до тех пор, пока он не выйдет из строя. Чтобы обеспечить пропускную способность WEB-приложений, необходимо выполнить кластерную обработку WEB-приложений.
С развитием современных технологий балансировка кластера/нагрузки стала относительно простой.Давайте познакомим с этими двумя понятиями студентов, которые только начинают работу, на простом языке:
Когда KFC открылся, было только одно окно заказа (сервер Tocmat, который может сэкономить затраты) для предоставления услуги заказа.Нет проблем с ежедневным заказом, и будет длинная очередь в одном окне (высокий параллелизм) во время еды время или выходные.. Жалобы есть не только у клиентов (долгое время ответа на запрос, плохое взаимодействие с пользователем), но и официант будет очень уставшим, и, наконец, в один прекрасный день он устанет (Tomcat кладет трубку).
В настоящее время сбоку добавляется окно (добавляется сервер Tomcat) для предоставления услуг по размещению заказов, но многие клиенты не знают новое окно, и в исходном окне все еще есть длинные очереди (пользователи по-прежнему имеют доступ к исходному Tomcat). ), затем человек стоит у двери и указывает покупателям, к какому окну заказывать в соответствии с ситуацией в очереди каждого окна (балансировщик нагрузки). Роль этого человека состоит в том, чтобы сделать количество заказов в каждом окне примерно равным, поэтому чтобы избежать того, чтобы некоторые окна были очень заняты, а некоторые очень заняты.Простоя.По мере увеличения количества клиентов окно заказа также будет соответственно увеличиваться (все больше и больше Tomcats).
- Кластер: группа серверов собирается вместе для предоставления услуг.В приведенном выше примере несколько окон заказов (несколько Tomcats) совместно предоставляют услуги заказа, что является кластером.
- Балансировка нагрузки. Поддерживайте сбалансированную нагрузку каждого окна заказа (каждого Tomcat) в кластере и не допускайте чрезмерного бездействия одного или нескольких из них.
Эти две концепции появляются одновременно: балансировка нагрузки для службы без кластера (один Tomcat) невозможна, а кластерная служба без балансировки нагрузки будет тратить ресурсы впустую.
Существует множество веб-решений для балансировки нагрузки,Nginx+TomcatЭто одно из наиболее часто используемых решений.Nginx действует как балансировщик нагрузки для разгрузки в соответствии с нагрузкой каждого Tomcat.
- Каждый Tomcat эквивалентен окну заказа и может предоставлять услуги заказа.
- Каждый раз, когда вы заказываете еду, вы должны сначала пройти через Nginx
- Nginx назначит пользователю, в какое окно заказывать еду, в зависимости от доступности каждого окна.
- Заказ в окне 1 в первый раз, повторный заказ сразу после заказа может быть назначен окну 2.
Давайте создадим веб-приложение для балансировки нагрузки.
1) Создать веб-приложение
Подготовьте веб-приложение, разверните его с двумя Tomcat и верните номер порта Tomcat в качестве результата, чтобы определить, какой Tomcat обрабатывает запрос во время тестирования.
/**
* 获取部署项目的Tomcat端口号
*/
@RequestMapping("/port/get")
@ResponseBody
public String getPort(HttpServletRequest request) {
return String.valueOf(request.getLocalPort());
}
В этом примере используйте5677, 5688Два порта развертывают проект./port/getЗапрос возвращает номер порта Tomcat
-
http:// localhost:5677/port/get: возврат 5677 -
http:// localhost:5688/port/get: возврат 5688
2) Nginx настроить балансировку нагрузки
Установка Nginx под Window относительно проста, студенты, которые не знают, как установить Baidu, могут кратко представить файл конфигурации Nginx:nginx.conf
# Nginx进程数
worker_processes 1;
events {
# 最大并发链接数
worker_connections 1024;
}
# Nginx处理HTTP请求相关的配置
# http不能重复, 全局唯一
http {
# 虚拟主机, 可配置多个虚拟主机
# Nginx监听88,89,90三个端口, 可配置三个server
server {
# 端口号, 访问88端口会都按照该server下的配置进行处理
listen 88;
# 主机名称
server_name localhost;
# 根据正则表达式匹配URL, 匹配到的URL按照该location下的配置进行处理
# /代表访问88端口的所有请求
location / {
# 静态资源所在根目录, 会从该目录下查找静态资源
# 例: 访问/a.html, 找到D:/a.html并返回
root D:/;
}
}
}
Самая базовая конфигурация Nginx из приведенного выше файла конфигурации, когда мы посещаемhttp://localhost:88Это будет обрабатываться Nginx.Далее мы настроим балансировку нагрузки Nginx.
- Настройте двух котов, определенных в 1), в
httpДобавьте следующий код под узел:
# 定义需要进行负载均衡的服务器信息
# upstream为关键字, springsession为自定义的名称
# server为关键字, 代表一个服务或服务(一个tomcat)
# server的内容为服务器的信息, 形式为ip:端口
# weight定义了服务器负载的权重, 每4次请求有3次转发到5688, 1次到5677
upstream springsession {
server localhost:5677 weight=1;
server localhost:5688 weight=3;
}
- Настройте, когда все запросы на доступ к Nginx перенаправляются на два сервера для обработки
location / {
# root D:/;
# 转发至名称为springsession的upstream处理
proxy_pass http://springsession;
}
3) Проверка балансировки нагрузки
доступhttp://localhost:88/port/get, Nginx перенаправляет запрос на обработку одному из двух котов, можно обнаружить, что результаты, возвращаемые запросом, отличаются
- В соответствии с настроенным весом каждые 4 посещения имеют 3 доступа по
5688вкл., 1 раз по5677иметь дело с. - Конфигурация веса - это только окончательное среднее значение 3/4 и 1/4, не обязательно первые три посещения будут
5688иметь дело с. - Когда вес не настроен, вероятность того, что два кота будут выделены одновременно, составляет 50% каждый.
Балансировка нагрузки настроена, есть такая проблема:
Когда вы заказываете еду в окне 1, вы временно сохраняете ключ в этом окне, и в следующий раз, когда вы заказываете еду, она может быть назначена окну 2 или другим окнам (она также может быть назначена окну 1), тогда, очевидно, можно получить ключ в других окнах Это не работает.Потому что в других окнах нет вашего ключа.В это время вы можете только молиться,чтобы вас быстро назначили на окно 1.
Если операция по сохранению ключа изменится на сохранение информации в СЕССИИ, то при выполнении вашего запроса
Tomcat1При обработке,Tomcat1СЕССИЯ будет сгенерирована для вас, вы задаете информацию в СЕССИИ, в следующий раз, когда ваш запрос будет назначенTomcat2иметь дело с,Tomcat2СЕССИЯ будет сгенерирована для вас снова. Это две независимые и не общие СЕССИИ, поэтому вы не можетеTomcat2получить вас вTomcat1информация, хранящаяся в .
Принцип входа в систему фактически заключается в сохранении статуса входа в SESSION.Согласно приведенному выше анализу, вход в службу, развернутую в кластере, будет недействительным.Если вы входите в Tomcat1, при следующем посещении Tomcat2 статус входа полученный SESSION должен быть недействителен. Войдите в систему, вам нужно войти снова. Пользователь сошел с ума, вы с ума сошли, босс будет с ума...
Если есть общее место для хранения вещей, и все окна заказов имеют доступ к вещам клиентов в общем месте, то вышеописанная проблема будет решена.
Вот смысл этой статьи:Унифицированное управление СЕССИЯ каждого WEB-приложения в рамках кластера.
-
выбор контейнера: Нам нужен контейнер, который может хранить SESSION единообразно. Из следующих трех пунктов,
RedisНесомненно самый подходящий. СЕССИЯ часто читается, поэтому база данных, файловая система не подходят, лучше всего работать с памятью. СЕССИЯ имеет идентификатор, идентификатор соответствует СЕССИИ, предпочтительно контейнеру K/V. СЕССИЯ чувствительна ко времени (долго не используется и нуждается в удалении) Лучше всего установить время истечения -
Механизм доступа SESSION: Поскольку SESSION генерируется Tomcat, первое, что приходит на ум, это модифицировать механизм Tomcat SESSION, начиная с
RedisЭто принесет проблему. Предположим, что Tocmat обновлен, нам нужно повторно изменить Tomcat. Следовательно, это решение менее осуществимо. Мы можем рассмотреть это, даже если Tomcat генерирует SESSION, мы все еще находимся в веб-приложении. Почему бы не перегенерировать a СЕССИЯ в ВЕБ-приложении, напишите такой фильтр, перед входом в ВЕБ-приложение откажитесь от СЕССИИ Томкэта, отRedisПолучить СЕССИИ в.
Так уж получилось, что есть такая структура, которая поможет нам реализовать вышеуказанную идею, и нам нужно только настроить ее для достижения унифицированного управления SESSION.Spring Session.
чтобыSpring SessionФункция впечатляет, давайте сначала проверим, как наше кластерное приложение обрабатывает SESSION без Spring Session.
Добавьте метод контроллера в наше веб-приложение для балансировки нагрузки, поместите каждыйSESSION IDВыведите его.
/**
* 获取部署项目的SESSION ID
*/
@RequestMapping("/sessionid/get")
@ResponseBody
public String getPort(HttpServletRequest request, HttpSession session) {
int port = request.getLocalPort(); // 端口
String sessionId = request.getSession().getId(); // SESSION ID
return "port: " + port + ", session id: " + sessionId;
}
Начать проект, множественный доступhttp://localhost:88/sessionid/get
- Оба посещения находятся под одним и тем же Tomcat
SESSOIN IDпостоянно - Два визита под разными Tomcat
SESSION IDменяется - После доступа к другому Tomcat при повторном доступе к тому же Tomcat
SESSION IDтакже меняется
Причины вышеописанной ситуации следующие:
- доступ
5677, поскольку СЕССИИ нет,Tomcat5677Создать SESSION, идентификатор1, и воля1Вернуться к клиенту - доступ
5677, переносимый браузеромSESSION_ID=1,Tomcat5677Найдите соответствующий SESSION. Таким образом, SESSION_ID равен1 - доступ
5688, переносимый браузеромSESSION_ID=1,Tomcat5688Не удалось найти соответствующий SESSION, повторно сгенерировать SESSION, идентификатор2, и воля2Вернуться к клиенту - доступ
5677, переносимый браузеромSESSION_ID=2,Tomcat5677Не удалось найти соответствующий SESSION, повторно сгенерировать SESSION, идентификатор3, и воля3Вернуться к клиенту - доступ
5688, переносимый браузеромSESSION_ID=3,Tomcat5688Не удалось найти соответствующий SESSION, повторно сгенерировать SESSION, идентификатор4, и воля4Вернуться к клиенту
4) Единое управление СЕССИЯ
Давайте использоватьSpring SessionДля управления СЕССИЯ ВЕБ-приложения
1) Установите Redis и включите его
см. статьюhttp://www.cnblogs.com/jaign/articles/7920588.html
2) Добавить зависимости Spring Session
// Spring Session依赖
"org.springframework.session:spring-session-data-redis:2.0.5.RELEASE",
// Redis依赖
"io.lettuce:lettuce-core:5.0.4.RELEASE"
3) Настроить фильтры сеанса Spring
существуетWeb.xmlСредняя конфигурацияSpring SessionПредоставленный фильтр, который в основном отвечает за замену СЕССИИ, сгенерированной Tomcat, на СЕССИЯ, сохраненную в Redis.
<!-- Spring Session过滤器 -->
<!-- 负责在进入WEB应用之前将Tomcat生成的SESSION替换为Redis中的SESSION -->
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4) Конфигурация SpringSession/Redis
Добавить в файл конфигурации SpringSpring Sessionнастроить иRedisнастроить
beans {
xmlns context: "http://www.springframework.org/schema/context"
// 启动注解方式
context.'annotation-config'()
// 配置Spring Session
// 实际上是配置Web.xml中使用的Spring Session过滤器
// 将Tomcat的Session替换为Redis中管理的Session
sessionConfig(RedisHttpSessionConfiguration)
// 配置Redis客户端连接
// 默认连接本地6379端口
lettuce(LettuceConnectionFactory)
}
5) Тест
Начать проект, множественный доступhttp://localhost:88/sessionid/get, посетить в любом случаеSESSION IDвсе так же.
в то же времяRedisЗапись текущей СЕССИИ также появляется в .
использоватьSpring SessionПроцесс обработки SESSION при доступе к WEB-приложению в рамках кластера:
- доступ
5677, из-заRedisНет вSESSION, поэтому будет генерироватьсяSESSIONи депозитRedis, идентификатор1, и воля1Вернуться к клиенту - доступ
5677, переносимый браузеромSESSION_ID=1,Tomcat5677существуетRedisнайти вSESSION. следовательноSESSION_IDза1 - доступ
5688, переносимый браузеромSESSION_ID=1,Tomcat5688существуетRedisнайти вSESSION. следовательноSESSION_IDза1 - Чисто
Redis, посетить снова5677, из-заRedisне имеет идентификатора в1изSESSION, поэтому он будет перегенерирован, и идентификатор изменится соответственно
5) Пример кода
На данный момент мы реализовали унифицированное управление SESSION, и вы можете найти один и тот же SESSION независимо от того, посещаете ли вы какой-либо TOMCAT.
Когда наше приложение сгруппировано, единое управление SESSION является обязательным. Существует много способов добиться единого управления SESSION. Эта статья — лишь один из них. Цель состоит в том, чтобы позволить учащимся понять важность единого управления SESSION и его основных принципов. .
- Пример кода адреса:
https://github.com/atd681/alldemo - Пример названия проекта:
atd681-springsession