Как запрограммировать обработку нескольких одновременных запросов от разных клиентов?

public class CassandraData {

    private static Session cassandraSession = null;
    private static Cluster cluster = null;

    CassandraData() {
        // Do nothing
    }

    static {

        if (cassandraSession == null) {
            QueryOptions qs = new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);

            PoolingOptions poolingOptions = new PoolingOptions();
            poolingOptions.setConnectionsPerHost(HostDistance.LOCAL, 2, 10).setConnectionsPerHost(HostDistance.REMOTE,
                    10, 20);

            SocketOptions socketOptions = new SocketOptions();
            socketOptions.setConnectTimeoutMillis(60000);
            socketOptions.setReadTimeoutMillis(600000);

            cluster = Cluster.builder().addContactPoints("***.***.***.***").withQueryOptions(qs)
                    .withPoolingOptions(poolingOptions).withSocketOptions(socketOptions)
                    .withLoadBalancingPolicy(new RoundRobinPolicy()).build();

            cassandraSession = cluster.connect("sf");
        }
        // monitor();
    }

    public Session getSession() {

        return cassandraSession;

    }
    public Data findOne(PK pk) {

        Data mc = null;

        Statement statement = new SimpleStatement(getCqlString(pk));

        ResultSet results = getSession().execute(statement);


        List<Row> rowList = results.all();

        if (rowList != null && rowList.size() > 0) {
            Row row = rowList.get(0);
            mc = EntityConvert.ConvertToMC(row);
        }

        return mc;
    }
}
    private String getCqlString(PK pk) {
    String cqlStr = "select * from table" + " where E='"
            + pk.E + "' and D=" + pk.D + " and M="
            + pk.M;
    return cqlStr;
}

Сервлет:

public class OneServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LogManager.getLogger(OneServlet.class);
    /**
     * @see HttpServlet#HttpServlet()
     */
    public OneServlet() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        long start = System.currentTimeMillis();

        PK pk = ValidData.getOnePk();

        CassandraData dataAccess = new CassandraData();
        long end2 = System.currentTimeMillis();
        Data mc = dataAccess.findOne(pk);

        String rsJson = JSON.toJSONString(mc);
        long end = System.currentTimeMillis();

        logger.info("Create CassandraData:" + (end2 - start)/1000.0 +"s elapsed." + "Show One:" + (end - start)/1000.0 +"s elapsed.");

        OutputStream out = response.getOutputStream();
        out.write(rsJson.getBytes("UTF-8"));
        out.flush();
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

В моем приложении сервлета я хотел бы использовать приведенный выше код для доступа к cassandra.
Когда пользователь обращается к сервлету, это займет в среднем 0,1 С, чтобы получить данные.
Когда несколько пользователей, например 60, получают доступ к сервлету, каждый запрос будет принимать в среднем 20s, чтобы получить данные.
Из-за нескольких пользователей, как я должен изменить этот код, чтобы уменьшить время requst?

1 ответ

  1. private Select getCqlSelect(PK pk) {
    
        Select select = QueryBuilder.select().from("table");
        select.where(QueryBuilder.eq("E", pk.E))
                .and(QueryBuilder.eq("D", pk.D))
                .and(QueryBuilder.eq("M", pk.M)).limit(1)
    
        return select;
    }
    

    Я использовал подготовленные заявления и улучшил производительность более чем в 20 раз.

    Подготовленное заявление

    Использование подготовленных инструкций дает множество преимуществ. Подготовленный оператор анализируется и подготавливается на узлах Cassandra и, таким образом, готов к будущему выполнению. При привязке по проводу передаются только эти параметры (и идентификатор запроса). Эти повышения производительности будут суммироваться при многократном использовании одних и тех же запросов (с различными параметрами).

    Помните, что правило для использования подготовленных операторов простое: подготовьте один раз, свяжите и выполните несколько раз.