1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.thrift;
20
21 import java.util.Arrays;
22 import java.util.List;
23
24 import org.apache.commons.cli.CommandLine;
25 import org.apache.commons.cli.CommandLineParser;
26 import org.apache.commons.cli.HelpFormatter;
27 import org.apache.commons.cli.Options;
28 import org.apache.commons.cli.PosixParser;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.hadoop.classification.InterfaceAudience;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.HBaseConfiguration;
34 import org.apache.hadoop.hbase.thrift.ThriftServerRunner.ImplType;
35 import org.apache.hadoop.hbase.util.InfoServer;
36 import org.apache.hadoop.hbase.util.VersionInfo;
37 import org.apache.hadoop.util.Shell.ExitCodeException;
38
39
40
41
42
43
44 @InterfaceAudience.Private
45 public class ThriftServer {
46
47 private static final Log LOG = LogFactory.getLog(ThriftServer.class);
48
49 private static final String MIN_WORKERS_OPTION = "minWorkers";
50 private static final String MAX_WORKERS_OPTION = "workers";
51 private static final String MAX_QUEUE_SIZE_OPTION = "queue";
52 private static final String KEEP_ALIVE_SEC_OPTION = "keepAliveSec";
53 static final String BIND_OPTION = "bind";
54 static final String COMPACT_OPTION = "compact";
55 static final String FRAMED_OPTION = "framed";
56 static final String PORT_OPTION = "port";
57
58 private static final String DEFAULT_BIND_ADDR = "0.0.0.0";
59 private static final int DEFAULT_LISTEN_PORT = 9090;
60
61 private Configuration conf;
62 ThriftServerRunner serverRunner;
63
64 private InfoServer infoServer;
65
66
67
68
69
70 public ThriftServer(Configuration conf) {
71 this.conf = HBaseConfiguration.create(conf);
72 }
73
74 private static void printUsageAndExit(Options options, int exitCode)
75 throws ExitCodeException {
76 HelpFormatter formatter = new HelpFormatter();
77 formatter.printHelp("Thrift", null, options,
78 "To start the Thrift server run 'bin/hbase-daemon.sh start thrift'\n" +
79 "To shutdown the thrift server run 'bin/hbase-daemon.sh stop " +
80 "thrift' or send a kill signal to the thrift server pid",
81 true);
82 throw new ExitCodeException(exitCode, "");
83 }
84
85
86
87
88
89 void doMain(final String[] args) throws Exception {
90 processOptions(args);
91
92 serverRunner = new ThriftServerRunner(conf);
93
94
95 int port = conf.getInt("hbase.thrift.info.port", 9095);
96 if (port >= 0) {
97 conf.setLong("startcode", System.currentTimeMillis());
98 String a = conf.get("hbase.thrift.info.bindAddress", "0.0.0.0");
99 infoServer = new InfoServer("thrift", a, port, false, conf);
100 infoServer.setAttribute("hbase.conf", conf);
101 infoServer.start();
102 }
103 serverRunner.run();
104 }
105
106
107
108
109 private void processOptions(final String[] args) throws Exception {
110 Options options = new Options();
111 options.addOption("b", BIND_OPTION, true, "Address to bind " +
112 "the Thrift server to. [default: " + DEFAULT_BIND_ADDR + "]");
113 options.addOption("p", PORT_OPTION, true, "Port to bind to [default: " +
114 DEFAULT_LISTEN_PORT + "]");
115 options.addOption("f", FRAMED_OPTION, false, "Use framed transport");
116 options.addOption("c", COMPACT_OPTION, false, "Use the compact protocol");
117 options.addOption("h", "help", false, "Print help information");
118 options.addOption(null, "infoport", true, "Port for web UI");
119
120 options.addOption("m", MIN_WORKERS_OPTION, true,
121 "The minimum number of worker threads for " +
122 ImplType.THREAD_POOL.simpleClassName());
123
124 options.addOption("w", MAX_WORKERS_OPTION, true,
125 "The maximum number of worker threads for " +
126 ImplType.THREAD_POOL.simpleClassName());
127
128 options.addOption("q", MAX_QUEUE_SIZE_OPTION, true,
129 "The maximum number of queued requests in " +
130 ImplType.THREAD_POOL.simpleClassName());
131
132 options.addOption("k", KEEP_ALIVE_SEC_OPTION, true,
133 "The amount of time in secods to keep a thread alive when idle in " +
134 ImplType.THREAD_POOL.simpleClassName());
135
136 options.addOptionGroup(ImplType.createOptionGroup());
137
138 CommandLineParser parser = new PosixParser();
139 CommandLine cmd = parser.parse(options, args);
140
141
142
143
144 List<String> commandLine = Arrays.asList(args);
145 boolean stop = commandLine.contains("stop");
146 boolean start = commandLine.contains("start");
147 boolean invalidStartStop = (start && stop) || (!start && !stop);
148 if (cmd.hasOption("help") || invalidStartStop) {
149 if (invalidStartStop) {
150 LOG.error("Exactly one of 'start' and 'stop' has to be specified");
151 }
152 printUsageAndExit(options, 1);
153 }
154
155
156 try {
157 if (cmd.hasOption(PORT_OPTION)) {
158 int listenPort = Integer.parseInt(cmd.getOptionValue(PORT_OPTION));
159 conf.setInt(ThriftServerRunner.PORT_CONF_KEY, listenPort);
160 }
161 } catch (NumberFormatException e) {
162 LOG.error("Could not parse the value provided for the port option", e);
163 printUsageAndExit(options, -1);
164 }
165
166
167 try {
168 if (cmd.hasOption("infoport")) {
169 String val = cmd.getOptionValue("infoport");
170 conf.setInt("hbase.thrift.info.port", Integer.valueOf(val));
171 LOG.debug("Web UI port set to " + val);
172 }
173 } catch (NumberFormatException e) {
174 LOG.error("Could not parse the value provided for the infoport option", e);
175 printUsageAndExit(options, -1);
176 }
177
178
179 optionToConf(cmd, MIN_WORKERS_OPTION,
180 conf, TBoundedThreadPoolServer.MIN_WORKER_THREADS_CONF_KEY);
181 optionToConf(cmd, MAX_WORKERS_OPTION,
182 conf, TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY);
183 optionToConf(cmd, MAX_QUEUE_SIZE_OPTION,
184 conf, TBoundedThreadPoolServer.MAX_QUEUED_REQUESTS_CONF_KEY);
185 optionToConf(cmd, KEEP_ALIVE_SEC_OPTION,
186 conf, TBoundedThreadPoolServer.THREAD_KEEP_ALIVE_TIME_SEC_CONF_KEY);
187
188
189 boolean compact = cmd.hasOption(COMPACT_OPTION) ||
190 conf.getBoolean(ThriftServerRunner.COMPACT_CONF_KEY, false);
191 conf.setBoolean(ThriftServerRunner.COMPACT_CONF_KEY, compact);
192 boolean framed = cmd.hasOption(FRAMED_OPTION) ||
193 conf.getBoolean(ThriftServerRunner.FRAMED_CONF_KEY, false);
194 conf.setBoolean(ThriftServerRunner.FRAMED_CONF_KEY, framed);
195 if (cmd.hasOption(BIND_OPTION)) {
196 conf.set(
197 ThriftServerRunner.BIND_CONF_KEY, cmd.getOptionValue(BIND_OPTION));
198 }
199
200 ImplType.setServerImpl(cmd, conf);
201 }
202
203 public void stop() {
204 if (this.infoServer != null) {
205 LOG.info("Stopping infoServer");
206 try {
207 this.infoServer.stop();
208 } catch (Exception ex) {
209 ex.printStackTrace();
210 }
211 }
212 serverRunner.shutdown();
213 }
214
215 private static void optionToConf(CommandLine cmd, String option,
216 Configuration conf, String destConfKey) {
217 if (cmd.hasOption(option)) {
218 String value = cmd.getOptionValue(option);
219 LOG.info("Set configuration key:" + destConfKey + " value:" + value);
220 conf.set(destConfKey, value);
221 }
222 }
223
224
225
226
227
228 public static void main(String [] args) throws Exception {
229 VersionInfo.logVersion();
230 try {
231 new ThriftServer(HBaseConfiguration.create()).doMain(args);
232 } catch (ExitCodeException ex) {
233 System.exit(ex.getExitCode());
234 }
235 }
236 }